JavaScript - 如何正确保存“this”的状态

时间:2013-05-02 04:50:51

标签: javascript jquery this

我有以下用于js学习目的的代码:

function A() {
    var self = this;

    this.test1 = function() {
        console.log("A_test1");
        B().test2();
        return self;
    } 

    this.problem = function() {
        console.log("I'm never called");
    }

    return self;
}

function B() {
    var self = this;

    this.test2 = function() {
        console.log("B_test2");
        return self;
    }  

    this.problem = function() {
        console.log("I'm a headach and overwrite others in my free time");
    }

    return self;
}

/*
 * This is our "main" function like in C
 */
$(function(){
    A().test1().problem();
});

我已经使用Firebug调试了代码。让我们一步一步地从“主要”功能检查下面一行: A()。test1()。problem();

1) A()
“关键字”this“不是一个函数(类)对象。它始终是”窗口“对象,它在运行时通过当前对象的属性/方法逐行扩展(在我们的例子中:A的当我们到达A()的末尾(即“返回自我”)时,“this”对象的内容如下:

  • “window”对象的所有属性/方法
  • a
  • 的test1()和problem()方法

2) A()。test1()
test1()方法的行为“B()。test2();”。所以它调用下一个B()

2.1) B()
当我们到达B()的末尾(即返回self)时,“this”对象内容如下:

  • “window”对象的所有属性/方法
  • test1()方法A.
    [A的问题()方法丢失,因为它被B]
  • 的问题()覆盖
  • 测试2()和问题()方法B

2.2) B()。test2()
这按预期运行并且没问题。所以我们用A()。test1()。

来完成

3) A()。test1()。problem();
这会调用B的problem()方法,虽然我想在这里调用A的问题()。

那么保存“this”对象的在线状态的正确方法是什么? (很明显,“self”在这里完全没有效果,因为它是“this”对象的引用(如C)。)

我可以在每个构造函数的开头克隆“this”-object的状态,即:
而不是

var self = this;

怎么样

var self = this.clone();

但我不确定这是不是一个好主意。导致克隆每个新创建的对象的“this”状态会在大型框架中杀死内存,不是吗?

我确信我不是第一个面对这个问题的人。我的Google搜索给了我的不多。那么保存“这个”的正确方法又是什么呢?我怎样才能在这个例子中调用A的问题()而不是B的问题()?

4 个答案:

答案 0 :(得分:2)

您需要使用A作为构造函数,即var a = new A(),然后这将指向一个新对象,而不是window

答案 1 :(得分:2)

var x = new A();
javascript中的

new关键字具有将this变量设置为新实例的功能。如果您在var x= A();函数中使用this而不是A,那么函数将为window(即全局上下文)。

对于这些简单设置,在需要回调之前不需要使用var self = this;,但为方便起见,您可以在没有任何副作用的情况下执行此操作。将变量的值设置为此值以使其保持一致是完全正确且非常常见的,变量的名称通常是that而不是self,但这只是糖。

答案 2 :(得分:1)

如果您在函数上调用new,那么this实际上将是对象的实例,而不是窗口......所以......

function Foo(){
   this.whatAmI = function(){
         console.log("I am " + this);  
   }
}


var bar = new Foo();
bar.whatAmI();

答案 3 :(得分:1)

其他答案(“使用new”)是正确的。

我想你会受益于John Resig的作品。看看他的书(Secrets of the Javascript Ninja)或在他的网站上查看the interactive Javascript tutorial