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

Pas*_*dis 54 javascript prototype

我对JavaScript原型概念的概念很新.

考虑以下代码:

var x = function func(){
}

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

var b = new x();
Run Code Online (Sandbox Code Playgroud)

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

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

Pet*_*son 74

只有构造函数具有原型.既然x是构造函数,x就有一个原型.

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

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

b.constructor
Run Code Online (Sandbox Code Playgroud)


the*_*tem 22

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

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

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

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

需要说明的是,[[Prototype]]酒店无法直接进入.它是一个内部属性,只能通过JS引擎提供的其他构造间接变化.


Ans*_*hul 13

在浏览代码之前,我想确保理解代码行为所需的原型概念.

  1. [[prototype]]是JavaScript对象的隐藏属性.这个隐藏属性只是一个链接Object.prototype(如果由对象文字创建).没有标准的方法来访问此[[prototype]]属性.
  2. JavaScript中的函数是对象,因此它们也具有[[prototype]]property.Here,如果是函数,则此隐藏属性是指向的链接Function.prototype.此处也没有标准方法来访问此[[prototype]]属性.
  3. 除了这个隐藏的链接[[prototype]],每当创建一个函数对象时,在其中创建一个prototype属性,该属性与隐藏[[prototype]]属性分开.

现在来看你的代码:

var x = function func(){}

执行此行时,将x使用两个链接创建一个函数对象:

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

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

我们现在知道这x是一个函数对象,因此x.prototype可以访问,所以在这里你可以包含log方法.

var b = new x();

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

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

  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.


Yuc*_*uci 13

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

__proto__可能无法跨浏览器可靠地使用.__proto__成为ECMAScript 6中的官方财产

但是,prototype属性是构造函数的一个属性,用于设置构造对象上将成为__proto__属性的内容.

您可以访问某些类型的prototype属性,例如核心JavaScript类型(日期,数组等).JavaScript函数(可以被视为构造函数)也具有公共原型属性.但是,函数的实例没有原型属性.

在你的情况下,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__);
Run Code Online (Sandbox Code Playgroud)

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

{log: ƒ, constructor: ƒ}
Run Code Online (Sandbox Code Playgroud)

而已.


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

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: ƒ}
Run Code Online (Sandbox Code Playgroud)