在JavaScript中,我们有两种方法可以创建"类"并赋予它公共功能.
方法1:
function MyClass() {
var privateInstanceVariable = 'foo';
this.myFunc = function() { alert(privateInstanceVariable ); }
}
Run Code Online (Sandbox Code Playgroud)
方法2:
function MyClass() { }
MyClass.prototype.myFunc = function() {
alert("I can't use private instance variables. :(");
}
Run Code Online (Sandbox Code Playgroud)
我读了很多次,人们说使用方法2效率更高,因为所有实例共享相同的函数副本而不是每个实例都有自己的副本.通过原型定义函数有一个巨大的缺点 - 它使得无法拥有私有实例变量.
即使理论上,使用方法1给对象的每个实例赋予它自己的函数副本(因此使用更多的内存,更不用说分配所需的时间) - 实际上实际发生了什么?似乎优化Web浏览器可以很容易地识别这种非常常见的模式,并且实际上让对象的所有实例引用通过这些"构造函数"定义的相同函数副本.然后,如果稍后显式更改,它只能为实例提供自己的函数副本.
关于两者之间的性能差异的任何见解 - 或甚至更好的现实世界经验 - 都将非常有帮助.
这可能会让你觉得这是一个语法不正确和可能是疯狂的问题,但这就是我的意思:当试图理解prototypeJavaScript中的概念时,我遇到了以下几个或多或少复杂版本的例子:
//Guitar function constructor
function Guitar(color, strings) {
this.color = color;
this.strings = strings;
}
//Create a new instance of a Guitar
var myGuitar = new Guitar('Black', ['D', 'A', 'D', 'F', 'A', 'E']);
//Adding a new method to Guitar via prototype
Guitar.prototype.play = function (chord) {
alert('Playing chord: ' + chord);
};
//Now make use of this new method in a pre-declared instance
myGuitar.play('D5');
Run Code Online (Sandbox Code Playgroud)
所以,关于我的问题:为什么你想要这样做?你为什么不直接把这个play功能放进Guitar去?为什么声明一个实例然后开始添加方法?我能看到的唯一原因是,如果你想myGuitar在play最初创建它时无法访问它,但我可以想出没有一个例子来说明为什么你会想要这样的东西.
看起来这样做会更有意义:
function Guitar(color, string) { …Run Code Online (Sandbox Code Playgroud) 我已经查看了SO上的所有其他(优秀)答案(尤其是:JavaScript关闭如何工作?)但我想要您对我对该概念的理解的反馈.
据我所知,一个用例是隐藏私有方法的实现,不受公共访问.
我想到的另一个是它作为工厂发电机:
<script>
function carFactory( make ) {
var m = make;
return { manufacture: function ( model )
{console.log("A " + m + " " + model + " has been created");}
}
}
toyotaFactory = carFactory("toyota");
hondaFactory = carFactory("honda");
toyotaFactory.manufacture("corolla");
toyotaFactory.manufacture("corolla");
hondaFactory.manufacture("civic");
</script>
Run Code Online (Sandbox Code Playgroud)
这输出:
A toyota corolla has been create
A toyota corolla has been created
A honda civic has been created
Run Code Online (Sandbox Code Playgroud)
那么你认为它是闭包的有效用例(即使用相同的代码库创建多个工厂)吗?或者我可以使用更好的东西来实现同样的目标吗?
请注意,问题不在于闭包的技术实现,而在于应用程序设计/开发中的有效用例.
谢谢.