Выяснить, что функция вызвана в режиме конструктора
Есть идеи, как внутри F различать способы вызова?
function F() {}
new F;
F.call(new F);
F();
обычно делаю так
function F() {
if (this.constructor == F) {
return 1;
}
return 2;
}
Но понадобилось отделить вариант с F.call(obj), и вот когда obj - это объект, созданный с помощью F, такая проверка не подходит. Нужно отделить способы запуска [[Construct]] и [[Call]]. |
я не вижу возможного решения.
т.е. как разделить эти два вызова ?
function F(){ this.a=function(){}; }
var a = new F;
var b = new F;
a.a();
// и
F.call( b ).a();
|
Ну решение есть:
function F() {
if (this.constructor == F) {
if (this._constructed) {
alert("F.call(new F)");
return null;
}
this._constructed = true;
return this;
}
return null;
}
new F;
F.call(new F);
F.call({});
F();
Просто может я торможу и еще как-то проще/лучше/надежнее можно сделать. Не очень хочется иметь ненужное enumerable-свойство в каждом объекте. |
Цитата:
|
Да смысл, надо будет помнить о дополнительных проверках для старых браузеров.
|
Цитата:
|
а зачем их отличать? constructor - обычный метод, который предназначен для инициализации объекта. запись ( new F( 1, 2, 3 ) ) - это просто грубо говоря более короткая запись следующей ( var obj= {}; obj.__proto__= F.prototype; return obj.constructor( 1, 2, 3 ) || obj )
|
function F(x) {
if (this.constructor == F) {
this.x = x;
}
return this.x;
}
var f = new F(3), obj = {x: 5};
alert(f.x); //3
alert(F.call(obj)); //5
*!*
alert(F.call(f)); //ожидаем получить 3, а будет undefined
*/!*
|
В конкретном примере было бы уместно проверять, передан ли аргумент:
if (this.constructor == F && arguments.length > 0) {
|
Обыграть то, что в случае вызова через new F сначала создается пустой объект, а потом уже к нему применяется конструктор. В случае с call'ом к объекту уже применён конструктор.
function F(x) {
if (this.constructor == F && this.sealed === undefined) {
this.x = x;
}
this.sealed = true;
return this.x;
}
var f = new F(3), obj = {x: 5};
alert(f.x); //3
alert(F.call(obj)); //5
alert(F.call(f)); //ожидаем получить 3, а будет 3
|
| Часовой пояс GMT +3, время: 19:30. |