我的JS有以下结构:
(function () {
this.Example = {
init: function () {
var self = this;
var self2 = Example;
$(document).ready(function () {
// THIS WORKS
Example.function1();
// THIS DOES NOT WORK
self.function1();
// THIS DOES NOT WORK EITHER
self2.function1();
});
console.log('init');
}(),
function1: function () {
console.log('function1');
},
function2: function () {
// THIS WORKS
Example.function1();
// THIS ALSO WORKS
this.function1();
// THIS ALSO WORKS
var self = this;
self.function1();
console.log('function2');
}
}
})();
我发现当我使用this
在对象文字中调用函数或在变量上声明它或使用Example
直接调用函数时,它可以正常工作。
但它在我的init()
中我必须使用文字名称并使用this
或在文档外声明变量仍然会导致错误。即使将变量声明为var self = Theme
,它也不起作用,我必须直接调用它。
为什么会这样?
答案 0 :(得分:0)
您的代码中有一些错误。首先,您的this
将指向全局window
对象。在您的示例中,您实际上是将Example
创建为全局变量。见这个例子:
注意:如果您使用的是ES5严格模式,则下面的代码实际上会抛出错误,因为this
未在严格模式下强制转换为window
。相反,您会将undefined
作为this
的值。
(function() { this.hi = 10; })();
console.log(window.hi); // prints 10

其次,您不应该在self
函数中将this
设置为init
,因为您的init
会立即在没有this
的上下文中执行已定义,因此this
将再次指向window
对象,如下例所示:
function Ex() {
this.Example = {
// this is coerced to window (in non-Strict Mode)
init: (function() { console.log(this === window )})()
}
}
var m = new Ex(); // prints true

第三,您不应该在self2
函数中将Example
设置为init
,因为Example
尚不存在。在下面的示例中,请注意obj
语句中未定义console.log
:
var obj = {
a : (function() { console.log(obj); })(), // undefined
b: 7
};

我看到它的方式,有几种不同的方法来实现你正在寻找的东西。与您当前使用的语法类似的最接近的解决方案如下所示:
修改:我添加了一些示例,说明如何在this
中注册事件处理程序时使用正确的init
,就像您在{{{}}示例中所做的那样1}}:
$(document).ready

进一步阅读:
MDN function Ex() {
this.Example = {
num: 5,
init: function() {
// synchronous call
this.function1();
// ES6 arrow function to reference "this"
setTimeout(() => console.log(this.num), 1000);
// < ES6 use bind()
setTimeout((function() {
console.log(this.num);
}).bind(this), 2000);
},
function1: function() { console.log(this.num); }
};
this.Example.init(); // call init() here
}
var m = new Ex(); // initialize your object.
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
答案 1 :(得分:-1)
基本上,您的范围并不是您认为的。调用事件后,您的范围会更改,并且不再是该对象。
成为&#34;懒惰&#34;让你的思维过程工作,尝试使用箭头功能。它更加宽容&#34;谈到范围。
以下代码将打印&#34; HI&#34;每次单击页面正文时都到控制台。
var obj = {
init: function(){
var self = this;
$(document).click(() => this.log("HI"));
},
log: function(txt){
console.log(txt);
}
}
obj.init();