命名空间JavaScript导致此操作不可用

时间:2017-11-20 14:30:26

标签: javascript

我的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,它也不起作用,我必须直接调用它。

为什么会这样?

2 个答案:

答案 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();