[英]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. 在浏览代码之前,我想确保理解代码行为所需的原型概念。
[[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]]
属性。 [[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]]
属性。 [[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
:
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 : 以下是关于原型的一些事实:
O
is created with O = new func(){}
then O[[prototype]] is Function.prototype
. 如果使用O = new func(){}
创建对象O
,则O [[prototype]]是Function.prototype
。 O
is created with O = {}
then O[[prototype]] is Object.prototype
. 如果使用O = {}
创建对象O
,则O [[prototype]]是Object.prototype
。 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.