简体   繁体   English

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

[英]JavaScript - how to save the state of “this” properly

I have the following code for js-learning purposes: 我有以下用于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();
});

I have debugged the code with Firebug. 我已经用Firebug调试了代码。 Let's examine the line below from "main" function step by step : A().test1().problem(); 让我们一步一步地检查“ main”函数中的以下行: A()。test1()。problem();

1) A() 1) A()
"The keyword "this" isn't a function(class) object. It is always the "window" object, that is extended line by line in the running time by the properties/methods of the current object (in our case: A's function object). So When we reach the end of A() (ie "return self"), the "this" object content is the following: “关键字“ this”不是函数(类)对象。它始终是“窗口”对象,在运行时根据当前对象的属性/方法逐行扩展(在我们的示例中:A的因此,当我们到达A()的末尾(即“返回自身”)时,“ this”对象的内容如下:

  • all properties/methods of the "window" object “窗口”对象的所有属性/方法
  • test1() and problem() methods of A A的test1()和problem()方法

2) A().test1() 2) A()。test1()
test1() method has the line "B().test2();". test1()方法的行为“ B()。test2();”。 So it calls as next B() 因此它称为下一个B()

2.1) B() 2.1) B()
When we reach the end of B() (ie return self), the "this" object content is the following: 当我们到达B()的末尾(即返回自身)时,“ this”对象的内容如下:

  • all properties/methods of the "window" object “窗口”对象的所有属性/方法
  • test1() method of A A的test1()方法
    [problem() method of A gets lost, because it is overwritten by the problem() of B] [A的problem()方法丢失了,因为它被B的问题()覆盖了]
  • test2() and problem() methods of B B的test2()和problem()方法

2.2) B().test2() 2.2) B()。test2()
This runs as expected and is OK. 这将按预期运行,并且可以。 So we are finsihed with A().test1(). 这样我们就可以使用A()。test1()了。

3) A().test1().problem(); 3) A()。test1()。problem();
And this calls the B's problem() method, although i want to call the A's problem() here. 尽管我想在这里调用A的问题(),但这将调用B的问题()方法。

So what is the proper way to save the online state of the "this" object? 那么,保存“此”对象的在线状态的正确方法是什么? (It's clear ,that "self" has no effect at all here since it is a reference (like in C) to "this" object.) (很明显,“自我”在这里根本不起作用,因为它是对“ this”对象的引用(就像在C中一样)。)

I could clone the "this"-object's state at the beginning of every constructor, ie: 我可以在每个构造函数的开头克隆“ this”对象的状态,即:
instead of 代替

var self = this;

how about that 那个怎么样

var self = this.clone();

But i'm not sure if it's a good idea. 但是我不确定这是个好主意。 Cause cloning the state of "this" for every newly created object would kill the memory in a large framework, wouldn't it? 导致为每个新创建的对象克隆“ this”状态会杀死大型框架中的内存,不是吗?

I'm sure that i'm not the first person that confrontates with this problem. 我确定我不是遇到这个问题的第一个人。 My Google searche gave me not much. 我的Google搜索给了我很多。 So again what is the proper way to save "this"? 那么,再次保存“ this”的正确方法是什么? How can i let A's problem() get called in this example instead of B's problem()? 在本示例中,我如何让A的问题()代替B的问题()被调用?

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

var x = new A();

new keyword in javascript has a feature that sets this variable to the new instance. javascript中的new关键字具有this变量设置为新实例的功能。 If you just use var x= A(); 如果只使用var x= A(); than this in A function would be window (ie. the global context). 超过thisA函数是window (即全球范围内)。

For these simple settings, you do not need to use var self = this; 对于这些简单的设置,您无需使用var self = this; until you need a callback, but for convenience, you can do that without any side effects. 直到需要回调为止,但是为了方便起见,您可以这样做而没有任何副作用。 Setting a variable's value to this to make it consistent is perfectly right and is very common, the variable's name is usually that instead of self but that's just sugar. 为此设置一个变量的值以使其一致是非常正确的,并且很常见,变量的名称通常是that的名称that而不是self但这只是糖。

If you call new on your function then this will, in fact, be an instance of the object and not the window... so... 如果您在函数上调用new ,那么实际上this将是对象的实例,而不是窗口...所以...

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


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

The other answers ("use new ") are right. 其他答案(“使用new ”)是正确的。

I think you would benefit from John Resig's works. 我想您将从约翰·雷西格的作品中受益。 Take a look at his book ( Secrets of the Javascript Ninja ) or check out the interactive Javascript tutorial on his web site. 看一看他的书( 《忍者的秘密》 ),或在他的网站上查看交互式Java教程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM