Javascript `new` 运算符和原型(prototype)

标签 javascript constructor prototype new-operator

假设我们创建了一个名为“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/

相关文章:

javascript - 如何在 mootools 中伪造事件?

javascript - 在导航栏中放置一个文本横幅

javascript - 如何使用 JavaScript 或 jQuery 克隆 HTML 元素的样式对象?

java - 当一个类从抽象类扩展时,如何访问它的私有(private)变量?

Java:使用非默认构造函数实例化通用对象

C++派生类链构造函数错误

javascript - 在 React 中使用相同处理函数切换多个 div 的优化方式

Javascript 构造函数

javascript - 对 "softBind"函数如何工作的困惑

c - 错误 : No previous prototype for function. 为什么会出现此错误?