简体   繁体   中英

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

I have the following code for js-learning purposes:

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. Let's examine the line below from "main" function step by step : A().test1().problem();

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:

  • all properties/methods of the "window" object
  • test1() and problem() methods of A

2) A().test1()
test1() method has the line "B().test2();". So it calls as next B()

2.1) B()
When we reach the end of B() (ie return self), the "this" object content is the following:

  • all properties/methods of the "window" object
  • test1() method of A
    [problem() method of A gets lost, because it is overwritten by the problem() of B]
  • test2() and problem() methods of B

2.2) B().test2()
This runs as expected and is OK. So we are finsihed with A().test1().

3) A().test1().problem();
And this calls the B's problem() method, although i want to call the A's problem() here.

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.)

I could clone the "this"-object's state at the beginning of every constructor, ie:
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?

I'm sure that i'm not the first person that confrontates with this problem. My Google searche gave me not much. So again what is the proper way to save "this"? How can i let A's problem() get called in this example instead of B's problem()?

您需要使用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. If you just use var x= A(); than this in A function would be window (ie. the global context).

For these simple settings, you do not need to use 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.

If you call new on your function then this will, in fact, be an instance of the object and not the window... so...

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


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

The other answers ("use new ") are right.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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