Javascript Class + Properties do not match their values

I am trying to create a class in javascript. I create it using an object of type JSON object.

Performing this action:

Foo = {
   PubId: '',

   Init:function( oCallback )
   {
         this.sendCommand( 'INIT', {}, oCallback );
   },

    sendCommand : function( sCommand, aParams, oCallback )
    {

        setTimeout( oCallback, 1000, '{"response":"INIT","time":1287982024,"pubid":"4cc50bc47c7b3"}' );

        return true;
    },
    onData : function( sData )
    {
        var aRes = JSON.parse( sData );

        this.PubId = aRes.pubid;
        alert( this.PubId );
        return this.PubId;
    },
    umtest:function(){ alert( this.PubId ); }
}

Then I also do this after the script is included:

Foo.Init( Foo.onData ); 

The problem is that this.PubId is updated inside the onData method, but outside of it, pubid is empty.

I am new to javascript classes, so I'm not sure what needs to be done, so I was hoping someone could help me. :)

Thank you for your time!

+3
source share
4 answers

. , this Javascript. Foo.onData setTimeout( oCallback, ...), this not Foo.

Foo this, :

sendCommand: function (sCommand, aParams, oCallback) {
    var that = this;           // save this reference
    setTimeout(function () {
        oCallback.call( that,  // call the function with it
               '{"response":"INIT","time":1287982024,"pubid":"4cc50bc47c7b3"}' );
    }, 1000);
    return true;
},

, , onData:

// is `this` really Foo or the global object?
alert(this === Foo);    // should be true
alert(this === window); // should be false

this Foo .

, , , , setTimeout, 1000 ms = 1s, , alert(Foo.PubId) Foo ( ).

, Foo.PubId :

// execute the check after 2s so as to
// make sure the callback has been called
setTimeout( function () {
  alert(Foo.PubId);
}, 2000);

.

+2

, , , ( this ) , . :

// Context: `this` is `myObj`
myObj.myMethod();

, , , :

// Context: `this` is the global object - `window` in a web browser
var myMethod = myObj.myMethod;
myMethod();

call apply, , :

// Context: `this` is `myObj`
var myMethod = myObj.myMethod;
myMethod.call(myObj);

, JavaScript bind. bind IE9, Firefox 4 Google Chrome Safari "" . , , ( MDC Function.prototype.bind):

// PARTIAL WORKAROUND for Function.prototype.bind  
if (!Function.prototype.bind)  
    Function.prototype.bind = function(context /*, arg1, arg2... */) {  
        'use strict';  
        if (typeof this !== 'function') throw new TypeError();  
        var _slice = Array.prototype.slice,  
            _concat = Array.prototype.concat,  
            _arguments = _slice.call(arguments, 1),  
            _this = this,  
            _function = function() {  
                return _this.apply(this instanceof _dummy ? this : context,  
                    _concat.call(_arguments, _slice.call(arguments, 0)));  
            },  
            _dummy = function() {};  
        _dummy.prototype = _this.prototype;  
        _function.prototype = new _dummy();  
        return _function;  
};  

:

Foo.Init( Foo.onData.bind(Foo) );
+1

onData .

:

Foo.Init(function(d) { Foo.onData(d);} ); 

.

0

This is a problem with the area. When you pass Foo.onDatayour function init, it "loses" the connection to the class. Functions are first class objects, so they can exist on their own. You can do the following:

Foo = {
   PubId: '',

   Init:function(oCallback, scope)
   {
         this.sendCommand('INIT', {}, oCallback, scope);
   },

    sendCommand : function(sCommand, aParams, oCallback, scope)
    {
        var cb = oCallback;
        if(scope) {
            cb = function(data) {
               oCallback.call(scope, data); 
            };
        }

        setTimeout( cb, 1000, '{"response":"INIT","time":1287982024,"pubid":"4cc50bc47c7b3"}' );

        return true;
    }
    //...
}

and then call it with

Foo.Init(Foo.onData, Foo);

The first parameter that is passed call()will become thisinside the method.

0
source

Source: https://habr.com/ru/post/1771312/


All Articles