JavaScript 'this' in different context

2019-07-19 09:26发布

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.

5条回答
我只想做你的唯一
2楼-- · 2019-07-19 09:41

See apply() and call().

parameters.userFunction.call(this, this.MyObjectCallback);
查看更多
霸刀☆藐视天下
3楼-- · 2019-07-19 09:49

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: {}
     }
});
查看更多
Rolldiameter
4楼-- · 2019-07-19 09:52

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.

查看更多
Bombasti
5楼-- · 2019-07-19 09:57

Try this.

            var myObject = {

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

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

查看更多
时光不老,我们不散
6楼-- · 2019-07-19 10:02

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.

查看更多
登录 后发表回答