我必须承认,JavaScript有时会出现奇怪的行为。
var Npc = function() {
this.name='Hello world';
}
Npc.attr='my new attribute';
console.log('>>>>'+Npc.attr); // my new attribute
console.log('>>>>'+Npc.name); // '' ????
var data = new Npc();
console.log('>>>>>' + data.attr); // undefined
console.log('>>>>>' + data.name); // Hello world
听起来很奇怪。 如果我能理解.name差异(实例与文字),我无法理解" attr"行为。
是COW吗?但是使用node.js调试器我真的看到了attr属性!?
... WAW
答案 0 :(得分:3)
这完全正常。
var Npc = function() {
this.name='Hello world';
}
是一个函数构造函数,直到你执行函数没有任何反应并且名称不存在,这是有意义的。
所以此时只定义了attr。
var data = new Npc();
console.log('>>>>>' + data.attr); // undefined
console.log('>>>>>' + data.name);
var data = new Npc();
会返回一个新对象,因为您使用的是new
。
如果要访问attr,则需要在该新对象中找到对Npc的引用
data.constructor.attr
是您可以找到attr
修改
答案 1 :(得分:1)
这里没什么奇怪的。
attr
是Npc
函数的属性
name
是Npc
用作构造函数时创建的对象的属性
因此,Npc
函数没有属性name
,Npc
创建的对象没有属性attr
。
答案 2 :(得分:1)
不要将构造函数与它产生的对象混淆。如果您希望属性自动传播到所有创建的对象 - 原型:
Npc.prototype.attr='my new attribute';
var data = new Npc();
console.log('>>>>>' + data.attr); // 'my new attribute';
答案 3 :(得分:1)
在您的第一个电话中,您直接呼叫Npc()
(即不是构造函数)。在这种情况下,函数体内的this
引用全局对象,在浏览器中是window
对象,在节点中是global
对象。无论哪种方式,您都将.name
属性分配给全局对象,因此您无法将其视为函数对象的属性(不要忘记函数在JavaScript中也是普通对象,除非与{{一起使用) 1}}运算符,它们不是构造函数)
在第二种情况下,您实际上将该函数用作构造函数,因为您将它与new
运算符一起使用。这里,正文中的new
实际上将this.name=...
属性添加到类型为name
的新实例化对象中。 Npc
运算符的magic
在第二种情况下将new
的含义赋予"the instantiated object"
关键字。
答案 4 :(得分:1)
如果您来自Java或C ++等类关键字语言,那么这可能会对您有所帮助。
在JavaScript中,函数可以用作对象的构造函数,就像在此处所做的那样:
var Npc = function() {
this.name='Hello world';
}
var data = new Npc();
通过松散与类关键字语言类比," name" property是一个在"类"中定义的实例变量。叫做Npc。所以表达式data.name是完全合乎逻辑的。
在JavaScript中,函数也是一个对象,这就是你在这里使用它的方式:
Npc.attr='my new attribute';
再次通过松散类比类关键字语言,Npc.attr就像一个静态类成员。因此attr是Npc的成员,而不是Npc的任何实例的成员。