这张图再次表明,每个对象都有一个原型。构造函数
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年)。
我认为你需要知道__proto__, [[prototype]]和prototype之间的区别。
公认的答案是有帮助的,但它可能暗示(不完全)__proto__只与在构造函数上使用new创建的对象相关,这是不正确的。
更准确地说:__proto__存在于每个对象上。
But what is __proto__ at all?
Well, it is an object referencing another object which is also a property of all objects, called [[prototype]].
It's worth mentioning that [[prototype]] is something that JavaScript handles internally and is inaccessible to the developer.
Why would we need a reference object to the property [[prototype]] (of all objects)?
Because JavaScript doesn't want to allow getting / setting the [[prototype]] directly, so it allows it through a middle layer which is __proto__. So you can think of __proto__ as a getter/setter of the [[prototype]] property.
What is prototype then?
It is something specific to functions(Initially defined in Function, i.e, Function.prototype and then prototypically inherited by newly created functions, and then again those functions give it to their children, forming a chain of prototypical inheritance).
JavaScript uses a parent function's prototype to set its child functions' [[prototype]] when that parent function is run with new (remember we said all objects have [[prototype]]? well, functions are objects too, so they have [[prototype]] as well). So when the [[prototype]] of a function(child) is set to the prototype of another function(parent), you will have this in the end:
let child = new Parent();
child.__proto__ === Parent.prototype // --> true.
(Remember child.[[prototype]] is inaccessible, so we checked it using __proto__.)
注意1:只要属性不在子对象中,它的__proto__将被“隐式”搜索。例如,if child。Myprop返回一个值,你不能说" Myprop "是子对象的属性,还是父对象原型的属性。这也意味着你永远不需要做这样的事情:child.__proto__.__proto__。我的东西你自己拿去吧,孩子。Myprop会自动为你做这件事。
注意2:即使父对象的原型中有项目,子对象自己的原型最初也是一个空对象。如果您想进一步扩展继承链(将child[ren]添加到child),则可以向其中添加项或手动从其中删除项。或者可以隐式地操纵它,例如使用类语法。)
注意3:如果你需要自己设置/获取[[prototype]],使用__proto__有点过时,现代JavaScript建议使用Object。setPrototypeOf和Object。getPrototypeOf代替。
为了解释,让我们创建一个函数
function a (name) {
this.name = name;
}
当JavaScript执行这段代码时,它将prototype属性添加到。prototype属性是一个具有两个属性的对象:
构造函数
__proto__
所以当我们这样做的时候
a.原型它返回
constructor: a // function definition
__proto__: Object
现在你可以看到构造函数就是函数a本身
而__proto__指向JavaScript的根对象。
让我们看看当我们使用带有new关键字的函数时会发生什么。
var b = new a ('JavaScript');
当JavaScript执行这段代码时,它会做4件事:
它创建了一个新对象,一个空对象// {}
它在b上创建__proto__,并使其指向a.prototype,因此b.__proto__ === a.prototype
它使用新创建的对象(在步骤#1中创建)作为上下文(this)执行a.p otype.constructor(这是函数a的定义),因此作为'JavaScript'传递的name属性(它被添加到this)被添加到新创建的对象。
它返回新创建的对象(在步骤#1中创建),因此var b被分配给新创建的对象。
现在如果我们添加a.prototype。car = "BMW"然后
b.car,输出“BMW”出现。
这是因为当JavaScript执行这段代码时,它在b上搜索car属性,它没有发现,然后JavaScript使用b.__proto__(在步骤#2中指向“a.prototype”)并找到car属性,因此返回“BMW”。
在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.
简介:
对象的__proto__属性是映射到该对象的构造函数原型的属性。换句话说:
实例。__proto__ ===构造函数。原型// true
这用于形成对象的原型链。原型链是一个对象属性的查找机制。如果访问对象的属性,JavaScript将首先查看对象本身。如果属性在那里没有找到,它将一路攀升到原链,直到它被找到(或没有)
例子:
人(姓名、城市){
This.name = name;
}
Person.prototype.age = 25;
const willem =新人(' willem ');
console.log(威廉。__proto__ === Person.prototype);//实例上的__proto__属性指向构造函数的原型
console.log (willem.age);// 25没有在willem object中找到它,但在prototype中存在
console.log (willem.__proto__.age);//现在我们直接访问Person函数的原型
第一个日志的结果为true,这是因为构造函数创建的实例的__proto__属性引用了构造函数的prototype属性。记住,在JavaScript中,函数也是对象。对象可以有属性,任何函数的默认属性都是一个名为prototype的属性。
然后,当这个函数被用作构造函数时,从它实例化的对象将接收一个名为__proto__的属性。这个__proto__属性引用了构造函数的prototype属性(默认情况下每个函数都有)。
为什么这个有用?
JavaScript在查找对象属性时有一种叫做“原型继承”的机制,下面是它的基本功能:
First, it's checked if the property is located on the Object itself. If so, this property is returned.
If the property is not located on the object itself, it will 'climb up the protochain'. It basically looks at the object referred to by the __proto__ property. There, it checks if the property is available on the object referred to by __proto__.
If the property isn't located on the __proto__ object, it will climb up the __proto__ chain, all the way up to Object object.
If it cannot find the property anywhere on the object and its prototype chain, it will return undefined.
例如:
人(名){
This.name = name;
}
let mySelf =新人(“威廉”);
console.log(我自己。__proto__ === Person.prototype);
console.log (mySelf.__proto__。__proto__ === Object.prototype);