Javascript 为什么不能在闭包中的私有函数内直接访问此属性?
在我自己的回答中,我指出JavaScript闭包的“公共”属性不能在“私有”函数中访问 那篇文章中给出的例子是Javascript 为什么不能在闭包中的私有函数内直接访问此属性?,javascript,closures,language-design,Javascript,Closures,Language Design,在我自己的回答中,我指出JavaScript闭包的“公共”属性不能在“私有”函数中访问 那篇文章中给出的例子是 function anobject(){ var privatefunction = function(){ //publicfunction(); //wrong; you have no access to it console.log(this); //refer to the global object, not the object c
function anobject(){
var privatefunction = function(){
//publicfunction(); //wrong; you have no access to it
console.log(this); //refer to the global object, not the object creating
};
this.publicfunction = function(){
console.log(this); //refer to the object creating
}
}
我认为原因是一些向后兼容性问题privatefunction
必须属于全局对象。因此,公共函数只是一个分配给this
属性的匿名函数。这就解释了为什么调用publicfunction
会失败,因为它需要先引用此
但是,以下修复仍然不起作用:
function anobject(){
var privatefunction = function(){
//publicfunction(); //wrong; you have no access to it
console.log(this); //refer to the object creating
}.bind(this);
this.publicfunction = function(){
console.log(this); //refer to the object creating
}
}
正如我明确指定的那样,privatefunction
应该与对象创建绑定,调用publicfunction
应该可以工作,但它不能。我必须做到以下几点:
function anobject(){
var privatefunction = function(){
this.publicfunction();
console.log(this); //refer to the object creating
}.bind(this);
this.publicfunction = function(){
console.log(this); //refer to the object creating
}
}
function anobject(){
var privatefunction = function(){
publicfunction();
console.log(this); //refer to the object creating
};
var publicfunction = function(){
console.log(this); //refer to the object creating
}
this.publicfunction = publicfunction;
}
另一种解决方法(我使用的方法)如下:
function anobject(){
var privatefunction = function(){
this.publicfunction();
console.log(this); //refer to the object creating
}.bind(this);
this.publicfunction = function(){
console.log(this); //refer to the object creating
}
}
function anobject(){
var privatefunction = function(){
publicfunction();
console.log(this); //refer to the object creating
};
var publicfunction = function(){
console.log(this); //refer to the object creating
}
this.publicfunction = publicfunction;
}
现在是问题部分。这种行为背后的原因是什么?在没有明确规范的情况下,通过禁用访问此的属性,它试图避免什么
更新:问题的主要部分是:当解释器在作用域链中找不到名称时,为什么不查看
this
属性?这里的问题是引用this
是由函数/方法的调用方确定的,例如:
function anobject(){
// here "this" is the object
var privatefunction = function(){
// here "this" is the object **that called privatefunction()**
};
this.publicfunction = function(){
// this method will always be called by the object, so "this" is the object
}
}
要实现您的目标,您还可以尝试以下方法:
function anobject(){
var that = this;
var privatefunction = function(){
[do what you like using "that"]
};
this.publicfunction = function(){
[here you can use "this" directly, or "that"]
}
}
在第二个示例中,
publicfunction()
被定义为对象的属性
this.publicfunction = function(){
console.log(this);
}
因此,此函数不能通过其名称直接访问publicfunction()
,并且与上下文无关。函数实际上不属于任何上下文,而是属于它是其属性的对象
在您的示例中,当privatefunction()
调用publicfunction()
时,这会引发一个错误,因为没有函数声明为名为publicfunction()
的变量,而不是,因为此
的属性不可访问:
function anobject(){
var privatefunction = function(){
//publicfunction(); // You cannot call publicfunction() because there is
// no function defined with this name
}.bind(this);
this.publicfunction = function(){
console.log(this);
}
}
看看这个例子,publicfunction()
即使在anobject()中也无法访问:
但是,如果在anobject()
的上下文中将publicfunction()
定义为变量,则可以通过其名称访问此函数。例如,您只需在anobject()的闭包中声明function publicfonment()
:
但在这种情况下,publicfunction()
在anobject()
的执行上下文之外是不可访问的,因此可以将其视为“私有”函数:
var a = new anobject();
if(typeof a.publicfunction === 'undefined')
console.log('Public function is undefined outside of anobject()');
因此,这就是为什么我们使用this
关键字来声明publicfunction()
:它使它可以在anobject()
的上下文之外访问,但这样做只能将此函数定义为anobject()
的属性
因此,访问此函数的唯一方法是调用this.publicfunction()
:
有关此
关键字的更多详细信息:
JavaScript中的变量与属性:我认为您对JavaScript中作用域的工作方式有一些误解。你可以在这里看一看:这与作用域无关,主要的问题是为什么当JavaScript找不到名称时,它没有查看this
对象?我几乎在我的帖子中解释了这一点。请仔细阅读。无论如何,您已经提供了另一种解决方法。您所说的privatefunction
技术就是调用它的对象。事实并非如此。如果我定义另一个公共函数并让它调用privatefunction
,那么如果我在测试中调用全局范围内的公共函数,这个
仍然是全局对象。正如我在回答中所说的,当你调用privatefunction()
时,即使在对象内部,因为你调用它的方式不是this.privatefunction()
(这是不可能的,因为它不是该对象的方法)然后,函数中的这个
是全局对象。如果我不够清楚,请告诉我,我会在有时间的时候更好地解释。好的。你是说在JavaScript中,没有对象前缀的名称总是指变量,而不是任何对象的属性吗?
function anobject(){
var privatefunction = function(){
this.publicfunction();
console.log(this);
}.bind(this);
this.publicfunction = function(){
console.log(this);
}
}