简体   繁体   English

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

[英]Why is JavaScript prototype property undefined on new objects?

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 x is its prototype. 据我了解, b.log()应该返回1,因为x是它的原型。 But why is the property b.prototype undefined? 但为什么属性b.prototype未定义?

Isn't b.prototype supposed to return the reference to the x function? 是不是b.prototype应该返回对x函数的引用?

Only constructor functions have prototypes. 只有构造函数具有原型。 Since x is a constructor function, x has a prototype. 由于x是构造函数, x具有原型。

b is not a constructor function. b不是构造函数。 Hence, it does not have a prototype. 因此,它没有原型。

If you want to get a reference to the function that constructed b (in this case, x ), you can use 如果要获取对构造b的函数的引用(在本例中为x ),则可以使用

b.constructor

The .prototype property 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 .prototype property points to. 创建新对象时,它将其内部[[Prototype]]属性设置为函数的.prototype属性指向的对象。

The object itself doesn't get a .prototype property. 对象本身不会获得.prototype属性。 Its relationship to the object is completely internal. 它与对象的关系完全是内部的。

That's why it works to do b.log() . 这就是为什么它可以用来做b.log() When the JS engine sees that the b object itself has no log property, it tries to look it up on the objects internal [[Prototype]] object, where it successfully finds it. 当JS引擎发现b对象本身没有log属性时,它会尝试在对象internal [[Prototype]]对象上查找它,并在其中成功找到它。

To be clear, the [[Prototype]] property is not directly accessible. 需要说明的是, [[Prototype]]属性不能直接访问。 It's an internal property that is only indirectly mutable via other constructs provided by the JS engine. 它是一个内部属性,只能通过JS引擎提供的其他构造间接变化。

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. [[prototype]]是JavaScript对象的隐藏属性。这个隐藏属性只是Object.prototype的链接(如果由对象文字创建)。没有标准的方法来访问这个[[prototype]]属性。
  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. JavaScript中的函数是对象,因此它们也具有[[prototype]]属性。这里,在函数的情况下,这个隐藏属性是到Function.prototype的链接。也没有标准方法来访问这个[[prototype]]属性。
  3. Apart from this hidden link [[prototype]] , Whenever a function object is created,a prototype property is created within it, which is separate from hidden [[prototype]] property. 除了这个隐藏链接[[prototype]] ,每当创建一个函数对象时,都会在其中创建一个prototype属性,该属性与hidden [[prototype]]属性分开。

Now coming to your code : 现在来看你的代码:

var x = function func(){} var x = function func(){}

When this line execute , a function object x is created with two links : 执行此行时,将使用两个链接创建函数对象x

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

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

as we know now that x is a function object so x.prototype is accessible, so here you are able to include log method with it. 我们现在知道x是一个函数对象,所以x.prototype是可访问的,所以在这里你可以包含log方法。

var b = new x(); var b = new x();

b is an object but not function object .It has that hidden link [[prototype]] but It is not accessible. b是一个对象但不是函数对象。它有隐藏的链接[[prototype]]但它不可访问。 so when you try to access like b.prototype it gives undefined as a result.If you want to check the prototype of b than you can see (x.prototype).isPrototypeOf(b); 所以当你尝试访问像b.prototype它会给出undefined作为结果。如果你想检查b的原型,你可以看到(x.prototype).isPrototypeOf(b); it will return true . 它会回归true so you can say that hidden link is referenced to x.prototype . 所以你可以说隐藏的链接被引用到x.prototype

Here are some facts about prototype : 以下是关于原型的一些事实:

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

All ordinary objects in JavaScript have an internal prototype slot (note: the prototype here does not refer to the prototype property). JavaScript中的所有普通对象都有一个内部原型槽(注意:这里的原型并不是指原型属性)。 The ECMAScript standard ( http://www.ecma-international.org/ecma-262/6.0/index.html ) specifies that this slot is referred to as [[Prototype]]. ECMAScript标准( http://www.ecma-international.org/ecma-262/6.0/index.html )指定此插槽称为[[Prototype]]。 You could access this slot through the __proto__ property. 您可以通过__proto__属性访问此插槽。

__proto__ may not be reliably available across browsers. __proto__可能无法跨浏览器可靠地使用。 __proto__ becomes an official property in ECMAScript 6 __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, eg, the core JavaScript types (Date, Array, and etc). 您可以访问某些类型的prototype属性,例如核心JavaScript类型(日期,数组等)。 Also a JavaScript function (, which can be regarded as a constructor) has a public prototype property. JavaScript函数(可以被视为构造函数)也具有公共原型属性。 However, instances of a function do not have a prototype property. 但是,函数的实例没有原型属性。

In you case, var b = new x(); 在你的情况下, var b = new x(); , b is an instance of function x. ,b是函数x的实例。 Thus b.prototype is undefined. 因此b.prototype是未定义的。 However, b does have an internal [[Prototype]] slot. 但是,b确实有一个内部[[Prototype]]槽。 If you output b.__proto__ in Google Chrome eg, version 63.0.3239.132, or Firefox such as version 43.0.4 如果您在谷歌浏览器中输出b.__proto__ ,例如版本63.0.3239.132,或版本43.0.4等Firefox

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: ƒ}

Because prototype is 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). 因为prototype是函数的属性(实际上是构造函数),因为它定义了这个类的对象的属性/方法(那些是从这个原型所属的构造函数创建的)。 Take a look at this link 看看这个链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 原型中具有数字属性的Javascript对象 - Javascript objects with number property in prototype Javascript原型属性返回函数中未定义的 - Javascript prototype property returning undefined in function 在JavaScript中充当原型对象的属性吗? - Function as a prototype's objects's property in Javascript? JavaScript原型属性未添加到其继承的对象 - JavaScript Prototype property not added to its inherited objects Javascript中的新对象是否具有原型属性? - Does a new object in Javascript have a prototype property? 原型方法中的事件处理函数,为什么认为.keyCode是JavaScript中未定义的属性? - Event Handler function in prototype's method, why does it think .keyCode is a property of undefined in JavaScript? 在Javascript中,为什么实例或对象文字没有“原型”属性? - In Javascript, why is there no “prototype” property for an instance or object literal? Javascript:为什么classList不是Element.prototype的属性 - Javascript: Why is classList not a property of Element.prototype Javascript原型的微妙之处:为什么'新'很重要 - Javascript prototype subtleties: why 'new' matters JavaScript原型属性和原型链接 - JavaScript prototype property and prototype link
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM