Closing does not work

var Dog = function() {

    var _instance = 'hello world';

    return function() {
        console.log(this._instance);
    }
} (); //note that it is self invoking function

var l = new Dog(); //#> undefined 

In the above case, I was expecting an exit:

'hello world'

Why this._instancedoes not get access to the variable, which should be available due to the closure? I tested this in FF and get undefined.

+3
source share
5 answers

You do not assign to the _instanceobject, it is just a closing variable, and it should be accessed without using this:

var Dog = function() {

    var _instance = 'hello world';

    return function() {
        console.log(_instance);
    }
} (); //note that it is self invoking function

var l = new Dog();

I would probably write it like this:

var Dog = (function() {

    var defaults = {
       name: 'Rags'
    };

    var Dog = function (options) {
        // Take options as a constructor argument, this
        // allows you to merge it with defaults to override
        // options on specific instances
        this.setOptions(options);
    };

    Dog.prototype = {
       // Common methods for Dogs here
       setOptions: function (options) {
          // Declare all variables in the beginning of the method because
          // JavaScript hoists variable declarations
          var key = null;
          // First assign all the defaults to this object
          for ( key in defaults) {
             this[key] = defaults[key];
          }
          // Now override with the values in options:
          if (options && options.hasOwnProperty) {
             for ( key in options ) {
                this[key] = options[key];
             }
          }
       }
    };

    return Dog; // Return the constructor method 
} ()); // wrap the self-invoked function in paranthesis to visualize that
       // it creates a closure

var buster = new Dog({name: 'Buster'}),
    unnamed = new Dog();

alert(buster.name); // Alerts 'Buster'
alert(unnamed.name); // Alerts 'Rags'

Please note that I did not try to compile the above code, so it may contain several errors. JsLint can't handle anything !

, setOptions, , , .., -.

, JQuery , () , setOptions:

function setOptions (options) {
   // I assume JQuery here
   // true as the first argument gives us a recursive merge
   var mergedOptions = $.extend(true, defaults, options);
   for (var key in mergedOptions ) {
      if(this.checkAllowedProperty(key, typeof(mergedOptions[key])) {
         this[key] = mergedOptions[key];
      }
   }
}

/**
 * This method checks if propertyName is an allowed property on this object.
 * If dataType is supplied it also checks if propertyName is allowed for
 * dataType
 * @return true if propertyName, with type dataType, is allowed on this object,
 * else false
 */
function checkAllowedProperty (propertyName, dataType);
+11

this.

+6

this._instance _instance. , (function() { ... })();, .

+4

, "". .

"this" . "this" , . , :

var Dog = function() {

    var _instance = 'hello world';
    var that = this;  //Assign "this" to "that"

    return function() {
        console.log(that._instance);  //Use reference to "that"
    }
} ();

var l = new Dog();

, - function.apply(), .

, .

+2

, "". , "this" , . , . , , , , . , , "this" .

What needs to be done so that the binding to "this" is bound to any particular object - this is a function call as a method of this object or its prototype. e.g. foo.myMethod (). Another way is that you can use the apply or call method, passing the object you want to apply to. e.g. anyFunction.apply (Foo).

+1
source

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


All Articles