Выяснить, что функция вызвана в режиме конструктора
Есть идеи, как внутри 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, время: 22:48. |