JS私有方法不会在每个构造函数调用时重新定义
JS Private methods not redefined at each constructor call
如何使Javascript私有方法每次调用构造函数时都不会重新定义?
据我所知,在OOP-JS中,私有方法是在一个"类"的"构造函数方法"中定义的方法,每次实例化一个新的"对象"时都会调用。我在想也许是一个函数声明(即 function name()
,而不是函数表达式 var name = function()
( 可以解决问题,但我如何确定以下代码只声明我的函数一次?
function Tester() {
function test () {
console.log("executed");
}
}
var t1 = new Tester();
var t2 = new Tester();
如何使每次调用构造函数时都不会重新定义的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
是完全私有的,只有匿名函数中的代码才能访问。它只有一个副本,但您可以像使用 privateFunction.call(this)
调用Tester
实例的方法一样调用它。
当然,或者,由于使用 call
比执行普通调用稍慢,因此您可以将实例作为参数传递:
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
还是传递参数主要是一种风格选择。
花了一段时间(来自ActionScript 3背景(,但我觉得我应该与你分享我如何学会停止担心并喜欢缺乏私人方法;)
许多流行的JavaScript库,如Backbone.js和js-Signals只是使用命名约定,其中前导下划线表示私有成员,而不是使用稍微深奥的语法(尽管每个都有自己的语法! 为了给这个额外的上下文,Python的文档甚至说Python根本不支持私有成员,并建议使用下划线。
JavaScript 是一种非常动态的语言;没有严格的类型检查和一些非常令人兴奋的范围界定;还有一些非常酷的库可以利用这些事实,例如 SinonJS,它可以毫不费力地在代码库中实现有意义的测试覆盖率;例如:
var instance = new Car("ford");
// Replace the car's engine with test stub.
// Alternative syntax: sinon.stub(instance, '_engine');
instance._engine = sinon.stub(instance._engine);
car.start();
// As the '_engine' object has been mocked it gains new attributes.
ok(instance._engine.checkOil.calledOnce, 'Oil level was checked');
抱歉,这个答案并没有真正回答你的问题(T.J的答案在这方面几乎是教科书( - 我只是认为提供另一种可能的解决方案是值得的。
- 为什么这个函数调用会破坏程序并导致未定义的变量
- 在JavaScript中调用函数时自定义此选项
- 具有不同函数调用定义的共享JavaScript文件
- 具有自定义函数调用的 HTML 表单
- 使用 jQuery 对动态创建的元素调用自定义函数
- 调用javascript函数时未定义
- eval调用函数,该函数调用定义函数的eval
- 如何获取从jQuery click()函数调用的特定于标记的自定义Javascript函数
- Angular2 在创建 ngSwitch 新视图后调用自定义函数
- 角度:创建可以调用作用域函数的自定义指令
- jQuery:点击事件后调用自定义函数
- 调用自定义数据属性中的函数
- jQuery 在单击时调用自定义函数
- JavaScript 自定义事件或普通函数调用中哪个更好
- 新打开的选项卡会终止函数调用
- 致命错误:调用未定义的函数 FusionCharts()
- 使用调试器从内部函数调用外部函数中定义的变量
- 如果函数调用被定义为var,如何调用它
- 带有此关键字的函数调用未定义
- 在Dojo中创建自定义小部件,错误地调用新小部件中的函数