2015-06-06 2 views
1

Цитирую this guy мы можем использовать конструктор питания, который имеет видJS Мощность Конструктор и InstanceOf без нового

function constructor() { 
    var that = {}; 
    that.data = true; 
    that.method = function() {}; 
    return that; 
} 

Для создания объектов, которые будут правильно вести себя с или без new ключевого слова.

Вопрос: как мы подключаем оператора intanceof к работе с конструкторами власти? Я думаю, что это имеет какое-то отношение к атрибуту object.prototype.constructor, но я не уверен, как его редактировать в области функции конструктора.

constructor() instanceof constructor // false but I want it to be true 
new constructor() instanceof constructor // true 
+0

Существует более простой подход: просто добавьте «использовать строго» в начало файла или в начало вашей функции конструктора. Это гарантирует, что 'this' не определено, если программист забыл использовать ключевое слово' new'. –

+0

См. Также: http://stackoverflow.com/questions/30419297/returning-this-from-a-constructor-function-in-js –

+0

@MattBrowne Я пытаюсь избежать «новой» своей школы мысли в js не использовать его. – t3dodson

ответ

3

Если вы пытаетесь купить в школа мышления в JS, что вы не должны использовать new, тогда вы отказываетесь от множества функций языка, включая instanceof.

instanceof идет рука об руку с JavaScript-функцией-конструктором + прототипной парадигмой наследования. x instanceof C конкретно смотрит на C.prototype и сравнивает его с цепочкой прототипов x (см. Алгоритм OrdinaryHasInstance). Поиск C.prototype предназначен для работы с оператором new, который при применении к любой функции F создаст новый объект с F.prototype в своей цепочке прототипов, на которой будет запускаться конструктор F (с , установленным для этого вновь выделенного объекта).

«Конструкторы питания» - это просто функции, которые возвращают объекты и не работают с обычным языковым оборудованием (включая классы ES2015). Попытка использовать instanceof с ними противоречива: если вы хотите поклясться new, вы должны поклясться instanceof.

Любые трюки, которые вы делаете, чтобы сделать instanceof Работа, как и в ответе Мэтта Брауна, в конечном итоге приведет к восстановлению всей инфраструктуры, которую уже предоставляет new. (См. a similar conversation I've had previously.)

+0

... и вы можете использовать 'isPrototypeOf()' вместо 'instanceof', как я упоминал в своем ответе. Я не согласен с Крокфордом в том, что «нового» нужно избегать, но если вы хотите его избежать, то «isPrototypeOf()» является жизнеспособной альтернативой, если вы знаете, что не можете полагаться на ' instanceof'. –

1

Вы можете использовать эту конструкцию

function constructor() { 
    if (!(this instanceof constructor)) 
     return new constructor(); 
    this.data = true; 
    this.method = function() { }; 
} 

Эта конструкция вы можете найти в Node.js родных модулей

Пример:

function Hash(algorithm, options) { 
    if (!(this instanceof Hash)) 
     return new Hash(algorithm, options); 
    this._handle = new binding.Hash(algorithm); 
    LazyTransform.call(this, options); 
} 
+0

Это не силовой конструктор. – t3dodson

0

Как я уже сказал в своем комментарии, я лично предпочитают просто использовать строгий режим, чтобы гарантировать, что программист не забудет использовать new ключевое слово. Но вот еще один способ сделать это, не используя new ключевое слово на всех:

function demo() { 
    var that = Object.create(demo.prototype); 
    that.data = true; 
    that.method = function() {}; 
    return that; 
} 

var d = demo(); 
d instanceof demo // true 

А вот альтернативный подход, который также позволяет избежать использования new:

var demo = { 
    init: function() { 
     this.data = true; 
    }, 
    method: function() {} 
} 
var d = Object.create(demo); 
d.init(); 

demo.isPrototypeOf(d) // true 
Смежные вопросы