为什么在新对象上未定义 JavaScript 原型属性?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14450731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 16:49:16  来源:igfitidea点击:

Why is JavaScript prototype property undefined on new objects?

javascriptprototype

提问by Pascal Paradis

I'm fairly new to the concept of JavaScript's prototype concept.

我对 JavaScript 原型概念的概念还很陌生。

Considering the following code :

考虑以下代码:

var x = function func(){
}

x.prototype.log = function() {
  console.log("1");
}

var b = new x();

As I understand it, b.log()should return 1 since xis its prototype. But why is the property b.prototypeundefined?

据我了解,b.log()应该返回 1 因为x它是它的原型。但是为什么属性b.prototype未定义?

Isn't b.prototypesupposed to return the reference to the xfunction?

b.prototype应该返回对x函数的引用吗?

回答by Peter Olson

Only constructor functions have prototypes. Since xis a constructor function, xhas a prototype.

只有构造函数有原型。因为x是构造函数,x有原型。

bis not a constructor function. Hence, it does not have a prototype.

b不是构造函数。因此,它没有原型。

If you want to get a reference to the function that constructed b(in this case, x), you can use

如果您想获得对构造函数的引用b(在本例中为x),您可以使用

b.constructor

回答by the system

The .prototypeproperty of a function is just there to set up inheritance on the new object when the function is invoked as a constructor.

.prototype当函数作为构造函数被调用时,函数的属性只是在新对象上设置继承。

When the new object is created, it gets its internal [[Prototype]]property set to the object that the function's .prototypeproperty points to.

创建新对象时,它会将其内部[[Prototype]]属性设置为函数.prototype属性指向的对象。

The object itself doesn't get a .prototypeproperty. Its relationship to the object is completely internal.

对象本身没有.prototype属性。它与对象的关系完全是内部的。

That's why it works to do b.log(). When the JS engine sees that the bobject itself has no logproperty, it tries to look it up on the objects internal [[Prototype]]object, where it successfully finds it.

这就是为什么它起作用的原因b.log()。当 JS 引擎发现b对象本身没有log属性时,它会尝试在对象内部[[Prototype]]对象上查找它,并成功找到它。

To be clear, the [[Prototype]]property is not directly accessible. It's an internal property that is only indirectly mutable via other constructs provided by the JS engine.

需要明确的[[Prototype]]是,该属性不能直接访问。它是一个内部属性,只能通过 JS 引擎提供的其他构造间接可变。

回答by Yuci

All ordinary objects in JavaScript have an internal prototype slot (note: the prototype here does not refer to the prototype property). The ECMAScript standard (http://www.ecma-international.org/ecma-262/6.0/index.html) specifies that this slot is referred to as [[Prototype]]. You could access this slot through the __proto__ property.

JavaScript 中的所有普通对象都有一个内部原型槽(注意:这里的原型不是指原型属性)。ECMAScript 标准 ( http://www.ecma-international.org/ecma-262/6.0/index.html) 指定此插槽称为 [[Prototype]]。您可以通过 __proto__ 属性访问此插槽。

__proto__ may not be reliably available across browsers. __proto__ becomes an official property in ECMAScript 6

__proto__ 可能无法跨浏览器可靠地使用。__proto__ 成为 ECMAScript 6 的官方属性

The prototype property is, however, a property on a constructor function that sets what will become the __proto__ property on the constructed object.

然而,prototype 属性是构造函数上的一个属性,它设置将成为构造对象上的 __proto__ 属性的内容。

You can access the prototype property of certain types, e.g., the core JavaScript types (Date, Array, and etc). Also a JavaScript function (, which can be regarded as a constructor) has a public prototype property. However, instances of a function do not have a prototype property.

您可以访问某些类型的原型属性,例如,核心 JavaScript 类型(日期、数组等)。同样,一个 JavaScript 函数(可以看作是一个构造函数)有一个公共的原型属性。但是,函数的实例没有原型属性。

In you case, var b = new x();, b is an instance of function x. Thus b.prototype is undefined. However, b does have an internal [[Prototype]] slot. If you output b.__proto__in Google Chrome e.g., version 63.0.3239.132, or Firefox such as version 43.0.4

在你的情况下,var b = new x();b 是函数 x 的一个实例。因此 b.prototype 是未定义的。但是, b 确实有一个内部 [[Prototype]] 插槽。如果您b.__proto__在 Google Chrome 中输出,例如 63.0.3239.132 版或 Firefox 版(例如 43.0.4 版)

console.log(b.__proto__);

You will see its [[Prototype]] slot as below:

你会看到它的 [[Prototype]] 槽如下:

{log: ?, constructor: ?}

That's it.

就是这样。



And just for your reference, the whole code snippet is put as below:

仅供参考,整个代码片段如下:

var x = function() {
};
x.prototype.log = function() {
  console.log("1");
}

var b = new x();
b.log();  // 1

console.log(b.prototype); // undefined
console.log(b.__proto__); // {log: ?, constructor: ?}
console.log(x.prototype); // {log: ?, constructor: ?}

回答by Anshul

Before going through your code I want to make sure some concept of prototype that are required to understand your code behavior.

在查看您的代码之前,我想确保了解您的代码行为所需的一些原型概念。

  1. [[prototype]]is a hidden property of a JavaScript object.This hidden property is nothing but a link to Object.prototype(If created by object literals).There is no standard way to access this [[prototype]]property.
  2. Functions in JavaScript are objects so they also have [[prototype]]property.Here, In case of function this hidden property is a link to Function.prototype.There is also no standard way to access this [[prototype]]property.
  3. Apart from this hidden link [[prototype]], Whenever a function object is created,a prototypeproperty is created within it, which is separate from hidden [[prototype]]property.
  1. [[prototype]]是 JavaScript 对象的隐藏属性。此隐藏属性只是指向Object.prototype(如果由对象文字创建)的链接。没有访问此[[prototype]]属性的标准方法。
  2. JavaScript 中的函数是对象,因此它们也具有[[prototype]]属性。在这里,对于函数,此隐藏属性是指向 的链接Function.prototype。也没有访问此[[prototype]]属性的标准方法。
  3. 除了这个隐藏链接[[prototype]],每当创建一个函数对象时,都会在其中创建一个prototype属性,该属性与隐藏[[prototype]]属性是分开的。

Now coming to your code :

现在来看看你的代码:

var x = function func(){}

var x = 函数 func(){}

When this line execute , a function object xis created with two links :

当这一行执行时,x会创建一个带有两个链接的函数对象:

  • Function.prototype (not accessible),
  • x.prototype (accessible).
  • Function.prototype(不可访问),
  • x.prototype(可访问)。

x.prototype.log = function() { console.log("1"); }

x.prototype.log = function() { console.log("1"); }

as we know now that xis a function object so x.prototypeis accessible, so here you are able to include log method with it.

正如我们现在知道的那样,它x是一个函数对象,因此x.prototype可以访问,因此您可以在这里包含 log 方法。

var b = new x();

var b = new x();

bis an object but not function object .It has that hidden link [[prototype]]but It is not accessible. so when you try to access like b.prototypeit gives undefinedas a result.If you want to check the prototype of bthan you can see (x.prototype).isPrototypeOf(b);it will return true. so you can say that hidden link is referenced to x.prototype.

b是一个对象而不是函数对象。它有那个隐藏的链接,[[prototype]]但它是不可访问的。因此,当您尝试访问时,b.prototype它会给出undefined结果。如果您想检查它的原型,b您会看到(x.prototype).isPrototypeOf(b);它会返回true。所以你可以说隐藏的链接被引用到x.prototype

Here are some facts about prototype :

以下是有关原型的一些事实:

  1. If object Ois created with O = new func(){}then O[[prototype]] is Function.prototype.
  2. If object Ois created with O = {}then O[[prototype]] is Object.prototype.
  3. If object Ois created with O = Object.create(obj)then O[[prototype]] is obj.
  1. 如果对象O是用创建的,O = new func(){}那么 O[[prototype]] 是Function.prototype
  2. 如果对象O是用创建的,O = {}那么 O[[prototype]] 是Object.prototype
  3. 如果对象O是用创建的,O = Object.create(obj)那么 O[[prototype]] 是obj

回答by Danilo Valente

Because prototypeis a property of functions (actually, constructors), since it defines the properties/methods of objects of this class (those which were created from the constructor this prototype belongs). Take a look at this link

因为prototype是函数(实际上是构造函数)的属性,因为它定义了此类对象的属性/方法(从该原型所属的构造函数创建的对象)。看看这个链接