Интригующее поведение при установке прототипа на конструкторе в javaScript - PullRequest
0 голосов
/ 24 ноября 2011

Начав с простой попытки, я определил конструктор и использовал его для создания экземпляра myobject:

function MyConstructor () {};
var myobject = new MyConstructor ();

Затем я изменил свойство prototype этого конструктора и создал другой экземпляр myobject1 с ним:

MyConstructor.prototype = {};
var myobject1 = new MyConstructor ();

Я повторил ту же процедуру и создал другой экземпляр myobject2:

MyConstructor.prototype = {name: '2'};
var myobject2 = new MyConstructor ();

Теперь я тестирую свойство constructor каждого экземпляра, котороеэто не то, что я ожидаю:

myobject.constructor == MyConstructor;
//true
myobject1.constructor == MyConstructor;
//false
myobject2.constructor == MyConstructor;
//false

При поиске [[прототипа]] он отличается друг от друга.

myobject.__proto__ == myobject1.__proto__
//false
myobject2.__proto__ == myobject1.__proto__
//false

Может кто-нибудь объяснить, что происходит с MyConstructorпри изменении его свойства prototype?

Ответы [ 3 ]

0 голосов
/ 24 ноября 2011

При создании конструктора:

function MyConstructor() {};

для его объекта prototype.constructor установлено значение MyConstructor:

MyConstructor.prototype.constructor === MyConstructor; //true

При перезаписи прототипа MyConstructor на

MyConstructor.prototype = { foo: function () {} };

затем оригинальный объект MyConstructor.prototype заменяется переданным объектом {foo: function () {}}, и этот объект не имеет свойства 'constructor', установленного в MyConstructor, но имеет функцию Object, потому что Object является конструктором, связанным со всем объектом, созданным литералами объекта.

Итак, после этого:

MyConstructor.prototype = { foo: function () {} };
MyConstructor.prototype.constructor === Object;

и когда вы создаете новый объект с этим конструктором

var foo = new MyConstructor();

, тогда:

foo.constructor === Object; // true

такЧтобы исправить эту проблему, после перезаписи прототипа необходимо исправить поле конструктора:

MyConstructor.prototype = { foo: function () {} };
MyConstructor.prototype.constructor = MyConstructor;

, и тогда у вашего конструктора будет прототип с правильным полем конструктора.Вы также можете написать:

MyConstructor.prototype = { foo: function () {}, constructor: MyConstructor };

и конечный эффект будет таким же.

0 голосов
/ 24 ноября 2011

Конструктор проводится по прототипу. Уничтожив прототип с помощью {}, вы фактически удалите любую ссылку на конструктор.

0 голосов
/ 24 ноября 2011

Пожалуйста, посмотрите на http://joost.zeekat.nl/constructors-considered-mildly-confusing.html

...