我宣布了这个功能:
function makePerson() {
this.first = 'John';
this.last = 'Oliver';
fullName = function(){
return this.first + this.last;
}
}
没有实例化它,而是调用了这个函数。
makePerson()
现在,我可以在全局访问中访问first
,last
和fullName
。
有人能解释我为什么会这样。
注意:我没有调用,而是实例化并检查。它不是全局的,可以在函数/类/对象范围内访问。
答案 0 :(得分:3)
这些是函数中this
关键字的正常语义。可以通过多种方式评估this
,具体取决于您调用函数的方式。我们假设我们的函数f
哪个正文包含this
关键字:
f(a,b)
中(标准函数调用语法)this
绑定到全局JavaScript Object
,这意味着如果在函数体中向this
添加属性,你实际上将它们添加到全球范围。anObject.f(a,b)
(方法调用语法)中,this
绑定到anObject
。new f(a,b)
(构造函数调用语法)中,this
绑定到正在构造的对象。 this
可能会引起混淆,只要函数体包含this
,该函数就会停止成为第一类。因此,我建议您尽量避免使用this
,as does Douglas Crockford。
如果您想制作工厂功能(我强烈建议您出于上述原因),您可以这样做:
function makePerson() {
var person = {
first: 'John',
last: 'Oliver'
};
person.fullName = function(){
return person.first + person.last;
};
return person;
}
如果您仍想构建一个构造函数,则约定规定该名称应为大写:
function Person() {
this.first = 'John';
this.last = 'Oliver';
this.fullName = function(){
return this.first + this.last;
};
}
最后,有充分的理由使用this
关键字,这就是原型继承。但是,我发现构造函数语法在这方面具有误导性。幸运的是,现在我们有Object.create
:
var personPrototype = {
fullName: function () {
return this.first + this.last;
}
};
function makePerson(first,last) {
var person = Object.create(personPrototype);
person.first = first;
person.last = last;
return person;
}
作为最后一个警告,以下是使用this
如何导致意外约束和混淆的示例:
var cn = makePerson("Chuck","Norris");
// works fine
console.log(cn.fullName());
// does not work, fullName is not a first-class function. You cannot detach it.
var fullName = cn.fullName;
console.log(fullName());