JS墙上的另一块砖

时间:2014-03-21 14:42:07

标签: javascript node.js anonymous-function object-literal

我必须承认,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

5 个答案:

答案 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

的地方

修改

  • 对data.constructor.attr纠正的小错误

答案 1 :(得分:1)

这里没什么奇怪的。
attrNpc函数的属性 nameNpc用作构造函数时创建的对象的属性 因此,Npc函数没有属性nameNpc创建的对象没有属性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的任何实例的成员。