__proto__为什么以及如何记住构造函数的旧属性's未定义的原型成员
Why and how __proto__ remembers old properties of the constructor function's undefined prototype member?
快速提示:请不要在回答中解释javascript继承的基础知识。
这里是一个简单的构造函数,它的原型成员附带了一些属性。
function Foo() {
this.relationship = "Love";
};
Foo.prototype.name = "Natalie";
Foo.prototype.age = 22;
Foo.prototype.country = "France";
现在,我们使用Foo创建新对象,并测试一些基础知识。一切都很酷。
var girl = new Foo();
girl.hasOwnProperty("relationship"); //=> true
girl.hasOwnProperty("name"); //=> false
girl.relationship; //=> "Love"
girl.name; //=> "Natalie", this comes from Foo.prototype
girl.__proto__ === Foo.prototype; //=> true
girl.__proto__.name === Foo.prototype.name; //=> true
girl.name === Foo.prototype.name; //=> true
如果我们更新Foo.prototype.name属性的值,那么girl.name会指向它应该指向的新值。
Foo.prototype.name = "Lucia";
girl.name; //=> "Lucia", this comes from Foo.prototype
当我们更改Foo.prototype并使其为空、未定义、空对象等时,会发生一件神秘的事情。
Foo.prototype = null;
如果我们的girl对象有一个隐藏的指向Foo.Prototype的__ proto__
(ECMA[[Prototype]])链接,那么在使Foo.Prototypenull之后,girl该没有机会获得name属性,但它确实有!
girl.name; //=> "Lucia"
girl.age; //=> 22
girl.country; //=> "France"
现在,如果我们在这一点上用Foo创建另一个对象。它没有名称、年龄和国家,因为Foo.prototype当然是null。
var new_girl = new Foo();
new_girl.name; //=> undefined
new_girl.age; //=> undefined
new_girl.country; //=> undefined
所以我的问题是,在我们将Foo.prototype分配给null之后,前一个对象(女孩)和他隐藏的__ proto__
链接究竟如何记住这些属性
它一点也不神秘,与继承无关
它与对象指针/引用有关。
var a = { name : "Bob", age : 32 };
var b = a;
b.name; // "Bob";
a.name = "Jim";
b.name; // "Jim";
a = null;
b.name; // "Jim";
发生了什么?
3和CCD_ 4被赋予指向同一对象的指针
当您更改对象的属性时,通过引用其中一个或另一个(在a
或b
上更改它们都无关紧要),另一个引用也会看到更改。
你不是在制作具有相同属性和值的新对象,你只是给它们同一个对象的地址,每次你问它们时,它们都在查找属性。
然后重新分配a
。
您不是在更改对象,而是在给a
一个到其他地方的地址b
仍然具有该地址。
所以现在这样想:
function Foo () { }
Foo.prototype = { name : "Bob", age : 32 };
var a = new Foo();
var b = new Foo();
a.__proto__ === Foo.prototype;
b.__proto__ === Foo.prototype;
Foo.prototype.age = 35;
a.age; // 35
b.age; // 35
// now we're replacing the `.prototype` reference with a brand new object
Foo.prototype = { name : "Sally", age : 16 };
a.__proto__ !== Foo.prototype;
b.__proto__ !== Foo.prototype;
a.name; // "Bob"
b.age; // 35
构造函数在后台所做的一切都是说:
this.constructor = arguments.callee;
this.__proto__ = this.constructor.prototype;
因此,当您更改this.constructor.prototype
和this.__proto__
引用的对象的属性时,其中任何一个的查找都会找到新值
但是从一个引用中删除引用不会删除另一个引用的对象。
如果这是你想要的结果,那么你需要删除原型的每个属性(无论你从哪里做——从函数还是从任何实例),然后通过将.prototype
设置为空对象来取消CCD_12(在较小的浏览器上为空会导致错误),这样未来的对象就无法访问。
- 为什么“;未定义的“;在JavaScript中结束循环
- 要求未定义JS回调参数
- 如何检查管道中未定义的项目
- TypeError:无法读取属性'推'未定义的JavaScript
- $window.ga在AngularJS事件中未定义
- 未捕获的TypeError无法读取未定义的属性socialsharing
- 为什么grunt contrib connect的中间件选项的第三个参数是未定义的
- console.log表示,当我调用对象的任何成员时,对象都是未定义的
- 成员变为未定义
- 如何避免在 JavaScript 中的数组中出现未定义的成员
- Javascript 全局数组访问成员未定义
- 无法设置未定义成员的属性
- 隔离作用域成员在链接/控制器内更新,但在传递给控制器时未定义
- 删除对象成员而不留下未定义的最好方法是什么?
- Import语句返回未定义的模块成员
- Javascript类成员在子类中是未定义的
- 原型编程- Javascript错误:这个.如果窗体未定义,则无法在成员方法中获取对象变量
- __proto__为什么以及如何记住构造函数的旧属性's未定义的原型成员
- 回调中未定义的方法和成员
- 数组的成员是未定义的,它拥有获取该成员所需的所有数据