我有以下用于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”对象的内容如下:
2) A()。test1()
test1()方法的行为“B()。test2();”。所以它调用下一个B()
2.1) B()
当我们到达B()的末尾(即返回self)时,“this”对象内容如下:
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的问题()?
答案 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。