__proto__VS。 JavaScript原型

本文翻译自:__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.ageperson2.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. prototypeconstructor()函数使用。 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]]以及其工作方式。

发布了0 篇原创文章 · 获赞 3 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/p15097962069/article/details/105455199