这张图再次表明,每个对象都有一个原型。构造函数
function Foo也有自己的__proto__,也就是function .prototype,
而它又通过__proto__属性再次引用
Object.prototype。因此,重复,Foo。原型只是一个显式
Foo的属性,引用b和c对象的原型。
var b = new Foo(20);
var c = new Foo(30);
__proto__和prototype之间有什么区别?
这一数据来自dmitrysoshnikov.com网站。
注:上述2010年的文章现在有第二版(2017年)。
我为自己画了一个小图,代表以下代码片段:
var Cat = function() {}
var tom = new Cat()
我有经典的OO背景,所以用这种方式表示层次结构很有帮助。为了帮助您阅读此图表,请将图像中的矩形视为JavaScript对象。是的,函数也是对象。;)
JavaScript中的对象有属性,__proto__只是其中之一。
此属性背后的思想是指向(继承)层次结构中的祖先对象。
JavaScript的根对象是object。Prototype和所有其他对象都是这个对象的后代。根对象的__proto__属性为null,表示继承链的结束。
你会注意到原型是函数的属性。Cat是一个函数,但function和Object也是(本机)函数。Tom不是一个函数,因此它没有这个属性。
此属性背后的思想是指向一个将在构造中使用的对象,即当您在该函数上调用new操作符时。
注意,原型对象(黄色矩形)有另一个属性称为
构造函数,它指向各自的函数对象。为
简短的原因,这是没有描述。
实际上,当我们用new Cat()创建tom对象时,所创建的对象的__proto__属性将被设置为构造函数的原型对象。
最后,让我们稍微研究一下这个图表。以下陈述是正确的:
汤姆。__proto__属性指向与Cat.prototype相同的对象。
猫。__proto__指向函数。原型对象,就像函数一样。__proto__和Object。__proto__做。
Cat.prototype。__proto__和tom.__proto__。__proto__指向相同的对象,即object .prototype。
干杯!
'use strict'
function A() {}
var a = new A();
class B extends A {}
var b = new B();
console.log('====='); // =====
console.log(B.__proto__ === A); // true
console.log(B.prototype.__proto__ === A.prototype); // true
console.log(b.__proto__ === B.prototype); // true
console.log(a.__proto__ === A.prototype); // true
console.log(A.__proto__ === Function.__proto__); // true
console.log(Object.__proto__ === Function.__proto__); // true
console.log(Object.prototype === Function.__proto__.__proto__); // true
console.log(Object.prototype.__proto__ === null); // true
在JavaScript中,每个对象(函数也是对象!)都有__proto__属性,该属性是对其原型的引用。
当我们使用new操作符和构造函数一起创建一个新对象时,
新对象的__proto__属性将被设置为构造函数的prototype属性,
然后构造函数将由new对象调用,
在这个过程中,“this”将是构造函数作用域中对新对象的引用,最终返回新对象。
构造函数的prototype是__proto__属性,构造函数的prototype属性是work with new操作符。
构造函数必须是函数,但函数并不总是构造函数,即使它具有prototype属性。
Prototype chain实际上是对象的__proto__属性,用于引用其原型,
以及原型的__proto__属性来引用原型的原型,等等,
直到引用Object的原型的__proto__属性,该属性引用为null。
例如:
console.log(a.constructor === A); // true
// "a" don't have constructor,
// so it reference to A.prototype by its ``__proto__`` property,
// and found constructor is reference to A
[[Prototype]]和__proto__属性实际上是一样的。
我们可以使用Object的getPrototypeOf方法来获取某个对象的原型。
console.log(Object.getPrototypeOf(a) === a.__proto__); // true
我们编写的任何函数都可以用new操作符创建一个对象,
这些函数中的任何一个都可以是构造函数。
只有一个对象用于原型链接。该对象显然有一个名称和值:__proto__是它的名称,prototype是它的值。这是所有。
为了让它更容易理解,看看这篇文章顶部的图表(由dmitry soshnikov绘制的图表),你永远不会发现__proto__的值指向prototype以外的其他东西。
要点是:__proto__是引用原型对象的名称,prototype是实际的原型对象。
这就像是在说:
let x = {name: 'john'};
X是对象名称(指针),{name: 'john'}是实际对象(数据值)。
注意:这只是一个非常简单的提示,说明它们在较高的水平上是如何相互关联的。
更新:下面是一个简单具体的javascript示例,以便更好地说明:
let x = new String("testing") // Or any other javascript object you want to create
Object.getPrototypeOf(x) === x.__proto__; // true
这意味着当Object.getPrototypeOf(x)为我们获取x的实际值(这是它的原型)时,正是x的__proto__所指向的。因此__proto__确实指向x的原型。因此__proto__引用x (x的指针),而prototype是x的值(它的原型)。
我希望现在大家都明白了。