我正在玩NodeJS,我注意到一些奇怪的事情。
我只是通过下面的代码探索构造函数的使用。
// We declare the constructor.
function Personne(inName) {
console.log("go!");
if ('undefined' != typeof inName) {
this.name = inName;
}
}
// We declare the object's prototype (that will be used by the constructor).
var PersonnePrototype = {
name: 'toto',
setName: function(inName) {
this.name = inName; // "this" refers to the new object being created.
},
getName: function() {
return this.name; // "this" refers to the new object being created.
}
};
Personne.prototype = PersonnePrototype;
var p = new Personne("Tom");
console.log("p.getName(): " + p.getName());
console.log(p);
console.log(Object.getPrototypeOf(p));
首先,我希望在使用运算符Personne(inName)
时执行构造函数new
中的代码。
显然,事实并非如此。下面,我给出执行的输出。
$ node loop-closure.js
p.getName(): toto
{ prototype: { name: false, setName: [Function], getName: [Function] } }
{ name: 'toto', setName: [Function], getName: [Function] }
您可以看到构造函数未执行...
但是,如果我在Chrome或Firefox上执行相同的代码,则会执行构造函数!
的FireFox:
"go!"
"Given: Tom"
"p.getName(): Tom"
Object { name: "Tom" }
Object { name: "toto", setName: window.onload/PersonnePrototype.setName(inName), getName: window.onload/PersonnePrototype.getName() }
铬:
go!
Given: Tom
p.getName(): Tom
Personne {name: "Tom", setName: function, getName: function}
Object {name: "toto", setName: function, getName: function}
我认为NodeJS是Chrome使用的JavaScript解释器。如果这是正确的,那么为什么Chrome和NodeJS之间的解释会有所不同?
更新
我看到了评论,我试着说:
我只是将代码复制/粘贴到文件中并在该文件上调用NodeJs。
是的,你是对的:它按预期工作。
然后我发现导致问题的原因。
我在执行的文件中有额外的代码。在我给你的代码之后,我已经发了一个return语句。下面,我给你完整的代码:
我使用的是NodeJs版本0.10.35:
$ node -v
v0.10.35
// We declare the constructor.
function Personne(inName) {
console.log("go!");
if ('undefined' != typeof inName) {
this.name = inName;
}
}
// We declare the object's prototype (that will be used by the constructor).
var PersonnePrototype = {
name: 'toto',
setName: function(inName) {
this.name = inName; // "this" refers to the new object being created.
},
getName: function() {
return this.name; // "this" refers to the new object being created.
}
};
Personne.prototype = PersonnePrototype;
var p = new Personne("Tom");
console.log("p.getName(): " + p.getName());
console.log(p);
console.log(Object.getPrototypeOf(p));
return;
console.log("Does the prototype has a constructor property ? " + Object.getPrototypeOf(p).hasOwnProperty('constructor'));
// Other way to say the same thing:
function Personne() {
this.prototype = {
name: false,
setName: function(inName) {
this.name = inName; // "this" refers to the new object being created.
},
getName: function() {
return this.name; // "this" refers to the new object being created.
}
}
};
var p = new Personne(); // Object "p" has a parent. This parent has been created by the prototype (which is a function).
p.setName("Tom");
console.log("The name is " + p.getName() + " / " + this.name);
console.log("Does the prototype has a constructor property ? " + Object.getPrototypeOf(p).hasOwnProperty('constructor'));
// Ou encore :
var p = Object.create(Personne.prototype);
p.setName("Tom");
console.log("The name is " + p.getName() + " / " + this.name);
// We can see the difference between the prototype and the instanced object.
// Both are objects.
// However, as you can see, they do not present the same properties.
utils.dump(Object.getPrototypeOf(p));
Object.getPrototypeOf(p).name;
utils.dump(p);
if (Object.getPrototypeOf(p).getName() != p.getName()) {
console.log("The prototype and the object have different properties.");
console.log("Prototype: " + Object.getPrototypeOf(p).getName());
console.log("Object: " + p.getName());
}
// ------------------------------------------------------------------------------------
// Heritage
// ------------------------------------------------------------------------------------
function Personne() {
this.prototype = {
name: false,
setName: function(inName) {
this.name = inName; // "this" refers to the new object being created.
},
getName: function() {
return this.name; // "this" refers to the new object being created.
}
}
};
function student() {
Personne.call(this);
}
我虽然返回语句后的代码没有干扰。显然,确实如此。
NodeJs在执行代码之前编译所有代码。因此,如果我稍后在代码中重新定义构造函数,那么它将修改它的第一次出现。
好的,但是:
var v = 1;
console.log("v = " + v);
var v = 2;
console.log("v = " + v);
输出:
$ node test1.js
v = 1
v = 2
和
var v = 1;
console.log("v = " + v);
return;
var v = 2;
console.log("v = " + v);
输出:
$ node test1.js
v = 1
并且(可能有引用的内容):
var v = { a: 1 };
console.log("v.a = " + v.a);
return;
var v = { a: 2 };
console.log("v.a = " + v.a);
输出:
$ node test1.js
v.a = 1
这里没什么不寻常的......返回语句之后的代码似乎没有改变return语句之前的代码。
@Alexey Ten
感谢您的提示。
Test1.js :
function Construct() { this.name = "Tom"; }
var v = new Construct();
console.log("v.name = " + v.name);
return;
function Construct() { this.name = "Joe"; }
Test2.js :
var Construct = function() { this.name = "Tom"; }
var v = new Construct();
console.log("v.name = " + v.name);
return;
var Construct = function() { this.name = "Joe"; }
Test1的结果是:v.name = Joe
Test1的结果是:v.name = Tom
答案 0 :(得分:0)
事实上,这篇文章不是关于NodeJs,而是关于吊装(感谢Alexey Ten)
很好的解释:
http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html
使用过C,C ++,Java,PHP,Perl,Tcl,Python或GO等语言后,我希望JavaScript在变量声明方面的行为方式相同。如果变量在使用之前未声明,则取决于语言:
在JavaScript中,结果取决于声明变量的方式。请注意,声明变量的方式决定了它的范围。提升意味着JavaScript将放置所有变量'如果变量的范围,则在开头声明。
var x; // Declaration
x = 10; // Initialization: this is the first time a value is affected to the variable.
x = 20; // Affectation.
换句话说:
(function() {
console.log("x = " + x + " f = " + f); // => x = undefined f = undefined
// Declaration + initialization
var x = 1;
var f = function() {};
})();
相当于:
(function() {
// Declaration
var x, f;
console.log("x = " + x + " f = " + f); // => x = undefined f = undefined
// initialization
x = 2;
f = function() {};
})();
这不等同于:
(function() {
try {
console.log("x = " + x + " f = " + f);
// initialization
x = 2;
f = function() {};
} catch(e) {
console.log("ERROR: " + e.message); // => ERROR: x is not defined (and f is not defined either).
}
})();
然而,小心!有一些微妙的捕获:
(function() {
try {
console.log("x = " + x + " f = " + f);
x = 1;
f = function() {};
} catch (e) {
console.log("ERROR: " + e.message); // => ERROR: x is not defined (and f is not defined either).
}
})();
// x and f should be defined ???
console.log("x = " + x + " f = " + f); // => ReferenceError: x is not defined.
应该定义x和f吗?实际上,定义x和f的代码没有被执行,因为之前引发了异常。如果你试试这个:
(function() {
try {
x = 1;
f = function() {};
} catch (e) {
console.log("ERROR: " + e.message);
}
})();
console.log("x = " + x + " f = " + f); // => x = 1 f = function () {}
OR:
(function() {
try {
console.log("x = " + x + " f = " + f); // => x = undefined f = undefined
x = 1;
f = function() {};
} catch (e) {
console.log("ERROR: " + e.message);
}
})();
console.log("x = " + x + " f = " + f); // => x = 1 f = function () {}
var x = 10, f;