Javascript 墙上的另一块砖

Javascript 墙上的另一块砖,javascript,node.js,anonymous-function,object-literal,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); // '' ??

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

它是一头牛吗?但是通过node.js调试器,我真的看到了attr atribute

哇…

这里没什么奇怪的。 attr是Npc函数的属性。 名称是将Npc用作构造函数时创建的对象的属性。
因此,Npc函数没有属性名,Npc创建的对象没有属性属性attr。

不要将构造函数与其生成的对象混淆。如果希望属性自动传播到所有创建的对象,请对其进行原型化:

Npc.prototype.attr='my new attribute';

var data = new Npc();
console.log('>>>>>' + data.attr);           // 'my new attribute';
这完全正常

var Npc = function() {
    this.name='Hello world';
}
是一个函数构造函数,在执行该函数之前,任何事情都不会发生,名称也不存在,这是有意义的

因此,在这一点上,只定义了attr

var data = new Npc();

console.log('>>>>>' + data.attr);           // undefined
console.log('>>>>>' + data.name);   
var数据=新Npc;返回一个新对象,这很有意义,因为您正在使用新对象

如果您想访问attr,您需要在新对象中找到对Npc的引用

data.constructor.attr是可以找到attr的地方

编辑

data.constructor.attr上的小错误已更正 在第一次呼叫中,您直接呼叫Npc,即不作为构造函数。在这种情况下,函数体中的this指的是全局对象,它在浏览器中是窗口对象,在节点中是全局对象。无论哪种方式,您都将.name属性分配给了全局对象,因此无法将其视为函数对象的属性。不要忘记,函数在JavaScript中也是普通对象,除非与新运算符一起使用,否则它们不是构造函数


在第二种情况下,您实际上将函数用作构造函数,因为您将它与新运算符结合使用。这里是this.name=。。。在主体内部,实际上向新实例化的Npc类型的对象添加了一个name属性。在第二种情况下,新操作符的魔法赋予了这个关键字的实例化对象。

< P>如果你来自java或C++之类的类关键字语言,那么这可能对你有帮助。 在JavaScript中,函数可以用作对象的构造函数,如下所示:

var Npc = function() {
    this.name='Hello world';
}
var data = new Npc();
通过与class关键字语言的松散类比,name属性是在名为Npc的类中定义的实例变量。因此表达式data.name完全符合逻辑

在JavaScript中,函数也是一个对象,这就是您在此处使用它的方式:

Npc.attr='my new attribute';

同样,通过与类关键字语言的松散类比,Npc.attr类似于静态类成员。因此attr是Npc的成员,而不是Npc任何实例的成员。

attr是构造函数的属性,而不是通过它创建的任何实例的属性。名字正好相反。你在问什么?在我看来,这是正确的行为。也许您应该阅读文档来创建对象。JavaScript:好的部分是一本关于这个主题的好书。作为C++程序员,我很抱歉这个代码听起来很奇怪:但是现在由于建设性的答案,我明白了。不要被语法所欺骗。除了if语句和for循环之外,JavaScript与C和friends有着巨大的区别。是的,Npc函数本身就是函数的一个对象实例,您可以在对象实例上动态添加成员。您可以尝试在Chrome中运行代码,并执行console.logNpc以查看Npc是什么类型的对象。因为它是一个函数,你可以用new调用它,并将它用作构造函数。更多关于构造函数和原型的信息可以在这里找到:好的,我明白了。。。但基本上,构造函数对象的目的是什么?