0

我有以下代码用于 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 调试了代码。让我们从“main”函数一步一步检查下面的行:A().test1().problem();

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

  • “窗口”对象的所有属性/方法
  • A 的 test1() 和 question() 方法

2) A().test1()
test1() 方法有一行“B().test2();”。所以它称为下一个 B()

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

  • “窗口”对象的所有属性/方法
  • A 的 test1() 方法 [A 的
    问题 () 方法丢失,因为它被 B 的问题 () 覆盖]
  • B 的 test2() 和 question() 方法

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

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

那么保存“this”对象的在线状态的正确方法是什么?(很明显,“self”在这里根本没有作用,因为它是对“this”对象的引用(就像在 C 中一样)。)

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

var self = this;

那个怎么样

var self = this.clone();

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

我敢肯定,我不是第一个遇到这个问题的人。我的谷歌搜索没有给我太多。那么再次保存“这个”的正确方法是什么?在这个例子中,我怎样才能让 A 的问题()而不是 B 的问题()被调用?

4

4 回答 4

2

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

于 2013-05-02T04:56:50.400 回答
2
var x = new A();

newjavascript 中的关键字具有将this变量设置为新实例的功能。如果你只是在函数中使用var x= A();than (即全局上下文)。thisAwindow

对于这些简单的设置,var self = this;直到需要回调时才需要使用,但为了方便,您可以这样做而没有任何副作用。将变量的值设置为此以使其一致是完全正确的并且很常见,变量的名称通常是that而不是,self但这只是糖。

于 2013-05-02T04:56:53.427 回答
1

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

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


var bar = new Foo();
bar.whatAmI();
于 2013-05-02T04:55:54.797 回答
1

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

我认为你会从 John Resig 的作品中受益。看看他的书(Javascript Ninja 的秘密)或查看他网站上的交互式 Javascript 教程。

于 2013-05-02T05:03:20.297 回答