JavaScript 'this' in different context

2019-07-19 09:21发布

问题:

I am trying to create a JavaScript object as follows.

var MyObject = function (parameters) {
    this.parameters = parameters;
    parameters.userFunction(this.MyObjectCallback);
}

MyObject.SOME_STATIC_VARIABLE = 21;

MyObject.prototype = {
    myObjectCallback: function() {
         console.log(this);
    }
}

The MyObject object will accept a userFunction to which it will pass a handler. The user function will do some logic and pass the result back to the instance, for example:

new MyObject({userFunction: function(callback) {
   $.post(
        'http://localhost/~knyttl/source.php',
        {},
        callback,
        'json');,
}});

Unfortunately, even though the callback is properly called, this gets an instance of the JQuery object and not of the MyObject instance as I would like. To conclude, I can not manage to keep the MyObject instance.

I am not even sure, whether this is a correct way of creating JavaScript objects. I will be grateful for any suggestion.

回答1:

You can bind a specific this value using .bind. Also I corrected the capitalizing of My.

parameters.userFunction(this.myObjectCallback.bind(this));

When you call a function like a.b(), then inside b, this === a. However, if you do not directly call it but only pass the function (like a.b) and call it later, this binding is lost.

.bind returns a new function which now receives the jQuery ajax result as this. However, it ignores that and calls myObjectCallback with the predefined (bound) this.

.bind is not available on older browsers but there are shims available.



回答2:

See apply() and call().

parameters.userFunction.call(this, this.MyObjectCallback);


回答3:

jQuery allows you to set the context of your callback.

You are in a weird situation where you design has hurt you. Your MyObject can't be passed in as the context, because it is being created at the same time.

new MyObject({userFunction: function(callback) {
   $.post(
        'http://localhost/~knyttl/source.php',
        {},
        callback,
        'json');,
}});

So instead:

var myObj = new MyObejct();
myObj.setCallback({userFunction: function (callback) {
     $.ajax({
         context: myObj,
         url: 'http://localhost/what ever /',
         success: callback,
         dataType: 'json',
         data: {}
     }
});


回答4:

Try this.

            var myObject = {

                obj1:function(paremeters){
                    this.Name = paremeters
                    return this},
                };

I would suggest you read, http://javascript.crockford.com/javascript.html



回答5:

Using this in javascript has the potential to be very confusing. It is assigned the value of whatever is behind the dot when the function is called e.g.

window.doSomething();

will cause this to be set to window, whereas

myDOMElement.onClick();

will cause this to be set to myDOMElement.

In your case, it comes down to JQuery's internal workings, so have a look at this very thorough set of explanations to get an understanding of how JQuery handles this.