构造函数与闭包?

时间:2013-09-19 18:11:48

标签: javascript constructor closures

这两个对象不同究竟是什么,a使用构造函数创建,b使用闭包?

属性__proto__对于使用闭包无法实现的任何内容是否有用?我应该在不同情况下使用这些技术吗?内存使用量有差异吗?

jsFiddle

window.MODULE = {};

MODULE.constructor = function(){
        this.publicVariable = 10;
};
MODULE.constructor.prototype.publicMethod = function(){
    return this.publicVariable;
};
//-------------------------------//
MODULE.closure = (function(){
    var publicMethod = function(){
        return this.publicVariable;
    };
    return function(){
        var obj = {};
        obj.publicVariable = 10;
        obj.publicMethod = publicMethod;
        return obj;
    };
}());
//-------------------------------//
var a = new MODULE.constructor();
console.log("constructor", a.publicMethod(), a)
var b = MODULE.closure();
console.log("closure", b.publicMethod(), b)

另请参阅具有一些私有和静态属性的more complicated jsFiddle comparison - 这两种技术的工作方式与我所知的相同......

3 个答案:

答案 0 :(得分:6)

粗略地说,原型继承(您的“构造函数”方法)的主要优点是可以更轻松地执行子类 monkeypatching (添加如果你想要私有实例变量和方法(“受保护的方法”仍然很难用这两种方法)或者更喜欢,那么闭包的方法很好>词法范围而不是使用“this”进行动态范围设定(如果有人setTimeout(obj.method, 1000)有用

至于性能,原型继承可以更高效,因为实现已经调整到它,但除非你从该类实例化批次对象,否则它真的无关紧要。


私有变量示例:

var counter  = function(){
   var count = 0; //private variable

   var increment = function(){ // private method
      count ++;
   };

   return { //public interface
      next: function(){
         increment();
         return count;
      },
   }
}

var c = counter();
console.log(c.next());
console.log(c.next());

答案 1 :(得分:1)

如果我们跳过OOP方法的优势,ab之间的差异是b拥有自己的方法publicMethod,当a继承此方法时从它的原型:

a.hasOwnProperty('publicMethod'); // false
b.hasOwnProperty('publicMethod'); // true

注意,__proto__属性是非标准的,并且在IE<中不受支持。 11.或者,您可以使用ES5功能Object.getPrototypeOf(a)

还要注意命名约为JavaScript 1

  • UPPER_CASE用于常量,当全局变量通常使用PascalCase时,MODULE应为Module;
  • 构造函数也使用PascaleCase,因此MODULE.constructor应为Module.Constructor

答案 2 :(得分:0)

有关原型,继承,覆盖和调用超级的更多内容:https://stackoverflow.com/a/16063711/1641941

MODULE={};
MODULE.constructor = function(){
  this.publicVariable = 10;
};
MODULE.constructor.prototype=(function(){
  var privateMethod=function(){
   console.log("I'm private");
  };
  return {
    publicMethod : function(){
      //going to call "private" method
      privateMethod();
      return this.publicVariable;
    }
  };
}());
var c = new MODULE.constructor();
c.publicMethod();

要具有特定于实例的“私有”成员值,您必须放弃原型,因为您必须在构造函数体中而不是在原型上定义访问这些值的所有函数。我个人认为强行实现JavaScript不支持的东西(私有实例特定变量)并放弃JavaScript(原型)支持的东西是愚蠢的。

支持我的意思是JS引擎会优化你的代码。