Objects literal and 'this' in submodule pa

2019-09-07 02:24发布

问题:

Im working in a sub-module pattern code. Want to create sub-modules with objects literals, the problem is this for the objects inside the sub-module is MODULE and not my object literal. Any idea?

var MODULE.sub = (function () {

   var myObject = {

       key: value,

       method: function () {
           this.key // this = MODULE and not MyObject... :(
       }

   };

   return myObject.method;

}(MODULE));

回答1:

This works for me:

var MODULE = MODULE || {};   
MODULE.sub = (function () {

   return {

       myObject : {

           key : 10,

           method : function() {
              console.log(this.key);
           }

       }
   };

})();

Then call it:

MODULE.sub.myObject.method();

You were only returning the method and not the key so "this" would be undefined. You could keep it private if you want like this and pass key in as a var:

  var MODULE = MODULE || {};
  MODULE.sub = (function () {

      var key = 10,

   return {

       myObject : {



           method : function() {
              console.log(key);
           }

       }
   };
})();


回答2:

Solved... just return a function in MODULE.sub calling the public method. I don't know if is the best approach

var MODULE.sub = (function () {

   var myObject = {

       key: value,

       method: function () {
           this.key // this = myObject :)
       }

   };

   return function () {
        myObject.method();
    }

}(MODULE));


回答3:

The this keywords value depends on how the function is called. So if you assign that function to MODULE.sub, and then invoke it as MODULE.sub(…), then this will point to the MODULE of course. If you had invoked it as myObject.method(…), then this would point to that object.

So you either should expose the whole myObject (like in @BingeBoys answer), or do not export that function and expect it to be a method of myObject. Instead, you could use a bound one:

return myObject.method.bind(myObject);

or the explicit equivalent of that

return function() {
    return myObject.method();
};

or you would not put the function as method on that object at all:

…
    var myObject = {
        key: value,
    };
    return function() {
        myObject.key // no `this` here
        …
    };
…