这张图再次表明,每个对象都有一个原型。构造函数 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年)。


当前回答

为了解释,让我们创建一个函数

 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”。

其他回答

解释性的例子:

function Dog(){}
Dog.prototype.bark = "woof"

let myPuppie = new Dog()

现在,myPupppie有__proto__属性指向Dog.prototype。

> myPuppie.__proto__
>> {bark: "woof", constructor: ƒ}

但是mypuppy没有原型属性。

> myPuppie.prototype
>> undefined

因此,mypuppie的__proto__是对用于实例化此对象的构造函数的.prototype属性的引用(当前mypuppie对象与此__proto__对象具有“委托”关系),而mypuppie的.prototype属性则根本不存在(因为我们没有设置它)。

MPJ的解释很好: 在JavaScript中创建对象

对于任何想要了解原型继承的人来说,这都是一个非常重要的问题。根据我的理解,默认情况下,当从函数中使用new创建对象时,prototype会被赋值,因为function定义了prototype对象:

function protofoo(){
}
var protofoo1 = new protofoo();
console.log(protofoo.prototype.toString()); //[object Object]

当我们创建一个普通的对象,没有new,即显式地从一个函数,它没有原型,但它有一个空的原型,可以分配一个原型。

var foo={
  check: 10
};
console.log(foo.__proto__); // empty
console.log(bar.prototype); //  TypeError
foo.__proto__ = protofoo1; // assigned
console.log(foo.__proto__); //protofoo

我们可以使用Object。创建以显式链接对象。

// we can create `bar` and link it to `foo`
var bar = Object.create( foo );
bar.fooprops= "We checking prototypes";
console.log(bar.__proto__); // "foo"
console.log(bar.fooprops); // "We checking prototypes"
console.log(bar.check); // 10 is delegated to `foo`

Prototype VS. __proto__ VS. [[Prototype]]

在创建函数时,会自动创建一个名为prototype的属性对象(不是您自己创建的),并将其附加到函数对象(构造函数)。注意:这个新的原型对象也指向本机JavaScript对象,或者有一个内部私有链接。

例子:

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;
}

如果你使用new关键字从Foo中创建一个新对象,你基本上是在创建一个新对象,它有一个内部或私有的链接到我们之前讨论过的函数Foo的原型:

var b = new Foo();

b.[[Prototype]] === Foo.prototype  // true

到该函数对象的私有链接称为双括号prototype或[[prototype]]。许多浏览器为我们提供了一个公共链接,称为__proto__!

更具体地说,__proto__实际上是一个属于原生JavaScript对象的getter函数。它返回this绑定的内部私有原型链接(返回b的[[prototype]]):

b.__proto__ === Foo.prototype // true

值得注意的是,ECMAScript5的启动,你也可以使用getPrototypeOf方法来获得内部的私有链接:

Object.getPrototypeOf(b) === b.__proto__ // true

注意:这个答案并不打算涵盖创建新对象或新构造函数的整个过程,而是帮助更好地理解__proto__、prototype和[[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);

prototype是Function对象的一个属性。它是由该函数构造的对象的原型。

__proto__是一个对象的内部属性,指向它的原型。当前标准提供了等效的Object.getPrototypeOf(obj)方法,尽管事实上的标准__proto__更快。

你可以通过比较函数的原型和对象的__proto__链来找到instanceof关系,你也可以通过改变prototype来打破这些关系。

function Point(x, y) {
    this.x = x;
    this.y = y;
}

var myPoint = new Point();

// the following are all true
myPoint.__proto__ == Point.prototype
myPoint.__proto__.__proto__ == Object.prototype
myPoint instanceof Point;
myPoint instanceof Object;

这里Point是一个构造函数,它程序化地构建一个对象(数据结构)。myPoint是一个由Point()构造的对象,所以Point。原型保存到myPoint。解析:句意:在那个时候。