关闭不起作用

Nic*_*ilt 3 javascript

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 
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我期待输出:

'你好,世界'

为什么this._instance不访问因闭包而应该可访问的变量?我在FF测试了这个并且未定义.

Pat*_*and 11

您没有分配_instance给对象,它只是一个闭包变量,应该在不使用的情况下访问this:

var Dog = function() {

    var _instance = 'hello world';

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

var l = new Dog();
Run Code Online (Sandbox Code Playgroud)

我可能会这样写:

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'
Run Code Online (Sandbox Code Playgroud)

请注意,我没有尝试编译上面的代码,因此它可能包含一些错误.没有什么JsLint无法处理!

您可能需要考虑向setOptions方法添加过滤,以便它不分配您不需要的属性,或过滤掉options-parameter中声明的方法等.

此外,如果您使用JQuery或类似的库,则有(通常)实用程序函数用于合并对象,这使得编写setOptions-method变得很简单:

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);
Run Code Online (Sandbox Code Playgroud)


Cha*_*ion 6

你的问题是this.