假设我们创建了一个名为“Shape”的函数,并在其原型(prototype)上添加了一个属性“name”和方法“toString”:
var Shape = function () {};
Shape.prototype.name = 'Shape';
Shape.prototype.toString = function () {
return this.name;
}
console.log(Shape.name); // ''
console.log(Shape.toString()); // function () {}
var Triangle = new Shape();
console.log(Triangle.name); // 'Shape'
console.log(Triangle.toString()); // 'Shape'
'NEW' 运算符做了两件事: 1. 它指向“三 Angular 形” 2.它将'Triangle的[[proto]]指向Shape.prototype
然后我可以理解当我在 Triangle 上调用 name & toString 时,它会搜索它的原型(prototype)链直到 Shape.prototype。
但我的问题是为什么 Shape 不为方法和属性搜索它的属性(即使它是一个对象)?
谢谢。
最佳答案
当您访问对象的属性时,Javascript 首先直接在对象上查找直接添加到对象的任何属性(这些称为“自己的”属性)。如果它在那里没有找到属性,那么它会查找原型(prototype)链。
所以,当你这样做时:
var Triangle = new Shape();
console.log(Triangle.toString()); // 'Shape'
它会在名为 Triangle 的实际对象上查找 .toString()
属性,但在该对象上没有直接使用该名称的属性。因此,由于它没有直接在对象上找到任何东西,它会查看原型(prototype)并在那里找到 Shape.prototype.toString()
实现,这就是执行的内容。
对原型(prototype)的引用在创建时存储在 Triangle 对象中。它不存储在 .prototype
属性中 - 该属性仅在构造函数中使用。相反,每个 JS 版本都有自己的方式来存储对原型(prototype)的引用,并且传统上所有浏览器的引用都不相同,而且它的存储方式是非标准的。它最初仅供 JS 引擎内部使用。例如,Chrome 将其存储在名为 obj.__proto__
的属性中,但 IE 不会。为了解决这种缺乏标准化的问题,有一种名为 obj.getPrototypeOf()
的新方法,现在可以在现代浏览器中使用它来访问给定对象的原型(prototype)。在任何情况下,当解析在实际对象本身上找不到的属性名称时,JS 引擎都会自动为您搜索此原型(prototype)。
如果你这样做:
var Triangle = new Shape();
Triangle.toString = function() {
return 'Shape named Triangle';
}
console.log(Triangle.toString()); // 'Shape named Triangle'
然后,javascript 将首先找到您直接附加到对象的 toString()
实现,然后它会执行该实现而不是原型(prototype)上的实现。
关于Javascript `new` 运算符和原型(prototype),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24924872/