Вопрос

I must confess, JavaScript has -sometimes- strange behaviors.

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

Sounds weird to me. If I can understand the .name difference (instance vs literal), I cannot understand the "attr" behavior.

Is it a COW ? But with the node.js debugger I really see the attr atribute !?

Waw...

Это было полезно?

Решение 2

If you're coming from a class-keyword language like Java or C++, then this might help you.

In JavaScript a function can be used as a constructor for an object, as you did here:

var Npc = function() {
    this.name='Hello world';
}
var data = new Npc();

By way of loose analogy to a class-keyword language, the "name" property is an instance variable defined in a "class" called Npc. So the expression data.name is perfectly logical.

In JavaScript a function is also an object, which is how you used it here:

Npc.attr='my new attribute';

Again by way of loose analogy to a class-keyword language, Npc.attr is like a static class member. So attr is a member of Npc and not a member of any instance of Npc.

Другие советы

It's perfectly normal.

var Npc = function() {
    this.name='Hello world';
}

is a function constructor,until you execute the function nothing happens and name doesnt exist,makes sense.

so at this point only attr is defined.

var data = new Npc();

console.log('>>>>>' + data.attr);           // undefined
console.log('>>>>>' + data.name);   

var data = new Npc(); returns a new object, makes sense because you are using new.

if you want to access attr you need to find a reference to Npc inside that new object

data.constructor.attr is where you will find attr

Edit

  • little mistake on data.constructor.attr corrected

Nothing strange here.
attr is the attribute of Npc function.
name is the attribute of object created when Npc is used as a constructor.
Therefore Npc function has no attribute name and object created by Npc has no attribute attr.

Don't confuse constructor function with objects it produces. If you want property to automatically propagate to all created objects - prototype it:

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

var data = new Npc();
console.log('>>>>>' + data.attr);           // 'my new attribute';

In your 1st call you call Npc() directly (i.e not as a constructor). In this case the this inside the body of the function refers to the global object, which in your browser is the window object and in node is the global object. Either way, you assigned the .name property to the global object and thus you cannot see it as a property of the function object (don't forget that functions are ordinary objects as well in JavaScript and unless used with the new operator, they are not constructors)

In the 2nd case you actually use the function as a constructor since you use it in conjunction with the new operator. Here the this.name=... inside the body actually adds a name property to the newly instantiated object of type Npc. It is the magic of the new operator that gives the meaning of "the instantiated object" to the "this" keyword in the 2nd case.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top