本文翻译自:__proto__ VS. prototype in JavaScript
This figure again shows that every object has a prototype. 该图再次显示每个对象都有一个原型。 Constructor function Foo also has its own
__proto__
which is Function.prototype, and which in turn also references via its__proto__
property again to the Object.prototype. 构造函数Foo还具有自己的__proto__
,即Function.prototype,而该__proto__
又通过其__proto__
属性再次引用了Object.prototype。 Thus, repeat, Foo.prototype is just an explicit property of Foo which refers to the prototype of b and c objects. 因此,重复一遍,Foo.prototype只是Foo的显式属性,它引用b和c对象的原型。
var b = new Foo(20);
var c = new Foo(30);
What are the differences between __proto__
and prototype
? __proto__
和prototype
什么区别?
The figure was taken from dmitrysoshnikov.com . 该图取自dmitrysoshnikov.com 。
#1楼
参考:https://stackoom.com/question/fmyl/proto-VS-JavaScript原型
#2楼
Prototype property is created when a function is declared. 声明函数时创建原型属性。
For instance: 例如:
function Person(dob){
this.dob = dob
};
Person.prototype property is created internally once you declare above function. 声明上述函数后,便会在内部创建Person.prototype属性。 Many properties can be added to the Person.prototype which are shared by Person instances created using new Person(). 可以将许多属性添加到Person.prototype中,这些属性由使用new Person()创建的Person实例共享。
// adds a new method age to the Person.prototype Object.
Person.prototype.age = function(){return date-dob};
It is worth noting that Person.prototype
is an Object
literal by default (it can be changed as required). 值得注意的是,默认情况下Person.prototype
是一个Object
文字(可以根据需要进行更改)。
Every instance created using new Person()
has a __proto__
property which points to the Person.prototype
. 使用new Person()
创建的每个实例都具有一个__proto__
属性,该属性指向Person.prototype
。 This is the chain that is used to traverse to find a property of a particular object. 这是用于遍历以查找特定对象的属性的链。
var person1 = new Person(somedate);
var person2 = new Person(somedate);
creates 2 instances of Person
, these 2 objects can call age
method of Person.prototype
as person1.age
, person2.age
. 创建2个Person
实例,这2个对象可以将Person.prototype
age
方法称为person1.age
和person2.age
。
In the above picture from your question, you can see that Foo
is a Function Object
and therefore it has a __proto__
link to the Function.prototype
which in turn is an instance of Object
and has a __proto__
link to Object.prototype
. 在上一个问题的图片中,您可以看到Foo
是一个Function Object
,因此它具有到Function.prototype
的__proto__
链接,而__proto__
则是Object
的实例,而具有到Object.prototype
的__proto__
链接。 The proto link ends here with __proto__
in the Object.prototype
pointing to null
. proto链接在此处以Object.prototype
__proto__
指向null
。
Any object can have access to all the properties in its proto chain as linked by __proto__
, thus forming the basis for prototypal inheritance. 任何对象都可以访问其通过__proto__
链接的原型链中的所有属性,从而构成原型继承的基础。
__proto__
is not a standard way of accessing the prototype chain, the standard but similar approach is to use Object.getPrototypeOf(obj)
. __proto__
不是访问原型链的标准方法,标准但相似的方法是使用Object.getPrototypeOf(obj)
。
Below code for instanceof
operator gives a better understanding: 下面的instanceof
运算符代码提供了更好的理解:
object instanceof
Class operator returns true
when an object is an instance of a Class, more specifically if Class.prototype
is found in the proto chain of that object then the object is an instance of that Class. 当对象是Class的实例时,对象instanceof
Class运算符将返回true
,更具体地说,如果在该对象的原型链中找到Class.prototype
,则该对象就是该Class的实例。
function instanceOf(Func){
var obj = this;
while(obj !== null){
if(Object.getPrototypeOf(obj) === Func.prototype)
return true;
obj = Object.getPrototypeOf(obj);
}
return false;
}
The above method can be called as: instanceOf.call(object, Class)
which return true if object is instance of Class. 上面的方法可以称为: instanceOf.call(object, Class)
,如果object是Class的实例,则返回true。
#3楼
A nice way to think of it is... 想到它的一种好方法是...
prototype
is used by constructor()
functions. prototype
由constructor()
函数使用。 It should've really been called something like, "prototypeToInstall"
, since that's what it is. 它实际上应该被称为"prototypeToInstall"
之类的东西,因为它就是这样。
and __proto__
is that "installed prototype" on an object (that was created/installed upon the object from said constructor()
function) 和__proto__
是对象上的“已安装原型”(已通过所述constructor()
函数在对象上创建/安装)
#4楼
my understanding is: __proto__ and prototype are all served for the prototype chain technique . 我的理解是:__proto__和prototype都用于原型链技术。 the difference is functions named with underscore(like __proto__) are not aim for developers invoked explicitly at all. 不同之处在于,以下划线命名的函数(例如__proto__)根本不面向显式调用的开发人员。 in other words, they are just for some mechanisms like inherit etc. they are 'back-end'. 换句话说,它们仅用于某些机制,例如继承等。它们是“后端”。 but functions named without underscore are designed for invoked explicitly, they are 'front-end'. 但是命名为不带下划线的函数是为显式调用而设计的,它们是“前端”。
#5楼
Another good way to understand it: 了解它的另一种好方法:
var foo = {}
/*
foo.constructor is Object, so foo.constructor.prototype is actually
Object.prototype; Object.prototype in return is what foo.__proto__ links to.
*/
console.log(foo.constructor.prototype === foo.__proto__);
// this proves what the above comment proclaims: Both statements evaluate to true.
console.log(foo.__proto__ === Object.prototype);
console.log(foo.constructor.prototype === Object.prototype);
Only after IE11 __proto__
is supported. 仅在支持IE11 __proto__
之后。 Before that version, such as IE9, you could use the constructor
to get the __proto__
. 在该版本(如IE9)之前,您可以使用constructor
获取__proto__
。
#6楼
Prototype VS. 原型VS。 __proto__ VS. __proto__VS。 [[Prototype]] [[原型]]
When creating a function, a property object called prototype is being created automatically (you didn't create it yourself) and is being attached to the function object (the constructor
). 创建函数时,将自动创建一个称为prototype的属性对象(您自己没有创建它),并将其附加到该函数对象( constructor
)上。
Note : This new prototype object also points to, or has an internal-private link to, the native JavaScript Object. 注意 :此新的原型对象还指向本机JavaScript对象,或具有本机JavaScript对象的内部-私有链接。
Example: 例:
function Foo () {
this.name = 'John Doe';
}
// Foo has an object property called prototype.
// prototype was created automatically when we declared the function Foo.
Foo.hasOwnProperty('prototype'); // true
// Now, we can assign properties and methods to it:
Foo.prototype.myName = function () {
return 'My name is ' + this.name;
}
If you will create a new object out of Foo
using the new
keyword, you basically creating (among other things) a new object that has an internal or private link to the function's prototype Foo
we discussed earlier: 如果要使用new
关键字从Foo
创建一个新对象,则基本上是在(除其他事项外)创建一个新对象,该对象具有内部或私有链接到我们先前讨论的函数原型Foo
:
var b = new Foo();
b.[[Prototype]] === Foo.prototype // true
The private linkage to that function's object called double brackets prototype or just
[[Prototype]]
.
对该函数对象的私有链接称为双括号prototype或简称为[[Prototype]]
。
Many browsers are providing us a public linkage to it that called __proto__
!
许多浏览器都向我们提供了一个名为__proto__
的公共链接!
To be more specific, __proto__
is actually a getter function that belong to the native JavaScript Object. 更具体地说, __proto__
实际上是属于本机JavaScript对象的getter函数 。 It returns the internal-private prototype linkage of whatever the this
binding is (returns the [[Prototype]]
of b
): 无论this
绑定是什么,它都会返回内部-私有原型链接(返回b
的[[Prototype]]
):
b.__proto__ === Foo.prototype // true
It is worth noting that starting of ECMAScript5
, you can also use the getPrototypeOf method to get the internal private linkage: 值得注意的是,从ECMAScript5
开始,您还可以使用getPrototypeOf方法获取内部私有链接:
Object.getPrototypeOf(b) === b.__proto__ // true
NOTE: this answer doesn't intend to cover the whole process of creating new objects or new constructors, but to help better understand what is
__proto__
, prototype
and [[Prototype]]
and how it works.
注意:此答案并不打算涵盖创建新对象或新构造函数的整个过程,而是有助于更好地理解__proto__
, prototype
和[[Prototype]]
以及其工作方式。