这两个对象不同究竟是什么,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 - 这两种技术的工作方式与我所知的相同......
答案 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方法的优势,a
和b
之间的差异是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引擎会优化你的代码。