这张图再次表明,每个对象都有一个原型。构造函数
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年)。
在JavaScript中,函数可以用作构造函数。这意味着我们可以使用new关键字从它们中创建对象。每个构造函数都带有一个内置对象。这个内置对象称为原型。构造函数的实例使用__proto__来访问其构造函数的prototype属性。
First we created a constructor: function Foo(){}. To be clear, Foo is just another function. But we can create an object from it with the new keyword. That's why we call it the constructor function
Every function has a unique property which is called the prototype property. So, Constructor function Foo has a prototype property which points to its prototype, which is Foo.prototype (see image).
Constructor functions are themselves a function which is an instance of a system constructor called the [[Function]] constructor. So we can say that function Foo is constructed by a [[Function]] constructor. So, __proto__ of our Foo function will point to the prototype of its constructor, which is Function.prototype.
Function.prototype is itself is nothing but an object which is constructed from another system constructor called [[Object]]. So, [[Object]] is the constructor of Function.prototype. So, we can say Function.prototype is an instance of [[Object]]. So __proto__ of Function.prototype points to Object.prototype.
Object.prototype is the last man standing in the prototype chain. I mean it has not been constructed. It's already there in the system. So its __proto__ points to null.
Now we come to instances of Foo. When we create an instance using new Foo(), it creates a new object which is an instance of Foo. That means Foo is the constructor of these instances. Here we created two instances (x and y). __proto__ of x and y thus points to Foo.prototype.
让我用一个简单的例子来解释:
function User(email, name){
this.email = email;
this.name = name;
this.online = false;
// method directly added to the constructor
this.greet = ()=>{
console.log(`Hi ${this.name}`);
}
}
// Adding prototype method login to the constructor function.
User.prototype.login = function(){
this.online = true;
console.log(this.email, 'has logged in');
};
// Adding prototype method logout to the constructor function.
User.prototype.logout = function(){
this.online = false;
console.log(this.email, 'has logged out');
};
var userOne = new User('ryu@ninjas.com', 'Ryu');
var userTwo = new User('yoshi@mariokorp.com', 'Yoshi');
console.log(userOne);
userTwo.login();
userTwo.greet();
输出:
结论:
在构造函数中添加的属性和方法是
直接添加到对象中。
添加的属性和方法
.prototype。被添加到对象的__proto__属性中。我们甚至可以看到userOne。__proto__或userTwo.__proto__