Javascript 从私有函数修改 public 属性
Javascript modify public properties from private functions
我在 JavaScript 中编写了一个 class,我正试图在私有函数中修改我的 public 属性之一。
这是我的代码示例:
MyClass = function(callback){
this.tabs = [];
var tabs_callback = function(){};
this.setTabsCallback = function(callback) {
tabs_callback = callback;
}
var _doStuff = function(callback) {
// doing stuff
this.tabs = [1, 2, 3];
console.log("Inside doStuff");
console.log(this.tabs);
tabs_callback();
}
this.doStuff = function() {
_doStuff();
}
}
var myObject = new MyClass();
myObject.setTabsCallback(function () {
console.log("Inside callback");
console.log(myObject.tabs);
});
myObject.doStuff();
这是我在控制台中得到的:
Inside doStuff
[ 1, 2, 3 ]
Inside callback
[]
为什么我在回调函数中看不到我的修改?
参见this keyword。使用箭头函数是防止这些问题的好方法:
var _doStuff = (callback) => { ...
不过你还是要注意一下。
默认情况下,JS不使用词法上下文绑定,当你调用普通函数时,this
默认为window
(如果是严格模式则为null
)。
有很多方法可以避免它:您可以将 this
保存到变量,如上所述。它在 100% 的情况下都有效。
您还可以使用 Function#bind
方法将 _doStuff 显式绑定到上下文:在初始化后执行类似 _doStuff = _doStuff.bind(this)
的操作,或者您可以将其称为 _doStuff.bind(this)()
。 IE9 之前的 IE(也许还有其他一些浏览器,我不太确定)不支持 bind
.
最后,你可以使用箭头函数,正如上面也提到的:他们使用词法绑定,this
将与你期望的相同。箭头函数自 ES6 以来可用,但是,我想,如果你正在制作这样的构造函数,它不是 ES6。
当通过
这样的函数调用_doStuf
时
this.doStuff = function() {
_doStuff();
}
_doStuff
绑定到全局对象。因此,您应该将其定义绑定到 this
或在调用 _doStuff
函数时使用 .call(this)
。因此,按如下方式修改您的代码会有所帮助;
MyClass = function(callback){
this.tabs = [];
var tabs_callback = function(){};
this.setTabsCallback = function(callback) {
tabs_callback = callback;
}
var _doStuff = function(callback) {
// doing stuff
this.tabs = [1, 2, 3];
console.log("Inside doStuff");
console.log(this.tabs);
tabs_callback();
} // <<< you can either use .bind(this) here
this.doStuff = function() {
_doStuff.call(this); // <<< or use .call(this) here to bind _doStuff to the this
}
}
var myObject = new MyClass();
myObject.setTabsCallback(function () {
console.log("Inside callback");
console.log(myObject.tabs);
});
myObject.doStuff();
因为 _doStuff
被定义为一个函数,它有自己的 this
上下文,这就是为什么你不能访问你在私有函数之外定义的 this.tabs
。
有两种简单的方法可以解决这个问题。
首先,您可以简单地创建一个私有变量,它在函数外保存对 this
的引用:
...
var that = this;
var _doStuff = function(callback) {
// inside _doStuff, use "that" instead of "this"
...
或者,其次,您可以改用箭头函数。箭头函数是对 Javascript 的一个相对较新的补充。它们不会创建具有自己的 this
引用的单独上下文,因此当您使用 this
对象时,它仍将引用与函数外部相同的对象,因此您的函数将正常工作:
....
var _doStuff = (callback) => {
// now _doStuff doesn't create a new "this" object, so you can still access the one from outside
...
我在 JavaScript 中编写了一个 class,我正试图在私有函数中修改我的 public 属性之一。
这是我的代码示例:
MyClass = function(callback){
this.tabs = [];
var tabs_callback = function(){};
this.setTabsCallback = function(callback) {
tabs_callback = callback;
}
var _doStuff = function(callback) {
// doing stuff
this.tabs = [1, 2, 3];
console.log("Inside doStuff");
console.log(this.tabs);
tabs_callback();
}
this.doStuff = function() {
_doStuff();
}
}
var myObject = new MyClass();
myObject.setTabsCallback(function () {
console.log("Inside callback");
console.log(myObject.tabs);
});
myObject.doStuff();
这是我在控制台中得到的:
Inside doStuff
[ 1, 2, 3 ]
Inside callback
[]
为什么我在回调函数中看不到我的修改?
参见this keyword。使用箭头函数是防止这些问题的好方法:
var _doStuff = (callback) => { ...
不过你还是要注意一下。
默认情况下,JS不使用词法上下文绑定,当你调用普通函数时,this
默认为window
(如果是严格模式则为null
)。
有很多方法可以避免它:您可以将 this
保存到变量,如上所述。它在 100% 的情况下都有效。
您还可以使用 Function#bind
方法将 _doStuff 显式绑定到上下文:在初始化后执行类似 _doStuff = _doStuff.bind(this)
的操作,或者您可以将其称为 _doStuff.bind(this)()
。 IE9 之前的 IE(也许还有其他一些浏览器,我不太确定)不支持 bind
.
最后,你可以使用箭头函数,正如上面也提到的:他们使用词法绑定,this
将与你期望的相同。箭头函数自 ES6 以来可用,但是,我想,如果你正在制作这样的构造函数,它不是 ES6。
当通过
这样的函数调用_doStuf
时
this.doStuff = function() {
_doStuff();
}
_doStuff
绑定到全局对象。因此,您应该将其定义绑定到 this
或在调用 _doStuff
函数时使用 .call(this)
。因此,按如下方式修改您的代码会有所帮助;
MyClass = function(callback){
this.tabs = [];
var tabs_callback = function(){};
this.setTabsCallback = function(callback) {
tabs_callback = callback;
}
var _doStuff = function(callback) {
// doing stuff
this.tabs = [1, 2, 3];
console.log("Inside doStuff");
console.log(this.tabs);
tabs_callback();
} // <<< you can either use .bind(this) here
this.doStuff = function() {
_doStuff.call(this); // <<< or use .call(this) here to bind _doStuff to the this
}
}
var myObject = new MyClass();
myObject.setTabsCallback(function () {
console.log("Inside callback");
console.log(myObject.tabs);
});
myObject.doStuff();
因为 _doStuff
被定义为一个函数,它有自己的 this
上下文,这就是为什么你不能访问你在私有函数之外定义的 this.tabs
。
有两种简单的方法可以解决这个问题。
首先,您可以简单地创建一个私有变量,它在函数外保存对 this
的引用:
...
var that = this;
var _doStuff = function(callback) {
// inside _doStuff, use "that" instead of "this"
...
或者,其次,您可以改用箭头函数。箭头函数是对 Javascript 的一个相对较新的补充。它们不会创建具有自己的 this
引用的单独上下文,因此当您使用 this
对象时,它仍将引用与函数外部相同的对象,因此您的函数将正常工作:
....
var _doStuff = (callback) => {
// now _doStuff doesn't create a new "this" object, so you can still access the one from outside
...