如何创建一个每次调用构造函数时都不会重新定义的 Javascript 私有方法?
你不能(好吧,请参阅下面的一些回旋余地)。但是,除非您将拥有数千个 的实例Tester
,否则不要太担心它;大多数引擎可能会在创建的多个函数对象中重用底层代码。(代码,注意;不是函数对象或它关闭的上下文,它们必须是唯一的并且每次都分配。但它们不必很大。当然,相当多的函数函数也相当小......)
...我如何确定以下代码只声明我的函数一次?
您可以确定它不会;每次Tester
调用它都会声明该函数。见证:
function Tester() {
this.test = test;
function test () {
console.log("executed");
}
}
var t1 = new Tester();
var t2 = new Tester();
console.log(t1.test === t2.test); // "false"
请注意,您可以拥有实现私有的函数,但不分配给对象的任何实例。模块模式可以很方便地做到这一点:
var Tester = (function() {
function Tester(name) {
this.name = name;
}
Tester.prototype.publicFunction = function() {
privateFunction.call(this);
};
function privateFunction() {
console.log("My name is " + this.name);
}
return Tester;
})();
var t = new Tester("Fred");
t.publicFunction(); // Outputs "My name is Fred" via the private function
在那里,privateFunction
它是完全私有的,只能由匿名函数中的代码访问。它只有一个副本,但您可以调用它,就好像您正在使用调用Tester
实例的方法一样privateFunction.call(this)
。
当然,或者,由于 usingcall
比执行普通调用稍慢,您可以将实例作为参数传递:
var Tester = (function() {
function Tester(name) {
this.name = name;
}
Tester.prototype.publicFunction = function() {
privateFunction(this);
};
function privateFunction(t) {
console.log("My name is " + t.name);
}
return Tester;
})();
var t = new Tester("Fred");
t.publicFunction(); // Outputs "My name is Fred" via the private function
当然,call
只有在出现问题时,额外的成本才是问题;除非你在一个紧密的循环中调用了数十万次,否则这不太重要。因此,是否使用call
和this
传递参数主要是一种风格选择。