这张图再次表明,每个对象都有一个原型。构造函数
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年)。
定义
(括号()内的数字是一个“链接”到下面写的代码)
原型-一个对象,包括:
=>函数(3)
prototype(5)
通过此构造函数(1)创建或将创建的对象(4)
=>构造函数本身(1)
=>此特定对象的__proto__ (prototype对象)
__proto__ (dandor prototype ?) -通过特定构造函数(1)创建的任何对象(2)和该构造函数的原型对象的属性(5)之间的链接,允许每个创建的对象(2)访问原型的函数和方法(4)(__proto__默认包含在JS中的每个对象中)
代码说明
1.
function Person (name, age) {
this.name = name;
this.age = age;
}
2.
var John = new Person(‘John’, 37);
// John is an object
3.
Person.prototype.getOlder = function() {
this.age++;
}
// getOlder is a key that has a value of the function
4.
John.getOlder();
5.
Person.prototype;
我知道,我迟到了,但让我试着简化一下。
假设有一个函数
function Foo(message){
this.message = message ;
};
console.log(Foo.prototype);
Foo函数将有一个原型对象链接。所以,无论何时我们在JavaScript中创建一个函数,它总是有一个原型对象链接到它。
现在让我们继续使用函数Foo创建两个对象。
var a = new Foo("a");
var b = new Foo("b");
console.log(a.message);
console.log(b.message);
现在我们有两个对象,对象a和对象b。它们都被创建了
使用构造函数Foo。记住,构造函数在这里只是一个词。
对象a和b都有message属性的副本。
这两个对象a和b链接到构造函数Foo的原型对象。
在对象a和b上,我们可以在所有浏览器中使用__proto__属性访问Foo prototype,在IE中我们可以使用Object.getPrototypeOf(a)或Object.getPrototypeOf(b)
现在,Foo。Prototype, a.__proto__和b.__proto__都表示同一个对象。
b.__proto__ === Object.getPrototypeOf(a);
a.__proto__ === Foo.prototype;
a.constructor.prototype === a.__proto__;
所有这些都将返回true。
如我们所知,在JavaScript中属性可以动态添加。我们可以向对象添加属性
Foo.prototype.Greet = function(){
console.log(this.message);
}
a.Greet();//a
b.Greet();//b
a.constructor.prototype.Greet();//undefined
如你所见,我们在Foo中添加了Greet()方法。但它可以在a和b或任何其他使用Foo构造的对象中访问。
在执行a.Greet()时,JavaScript将首先在对象a的属性列表中搜索Greet。如果没有找到,它将在a. Since a.__proto__和Foo的__proto__链中上升。prototype是同一个对象,JavaScript会找到Greet()方法并执行它。
我希望,现在prototype和__proto__被简化了一点。
我为自己画了一个小图,代表以下代码片段:
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。
干杯!