我从来没有真正使用过JavaScript,但我大致知道它是什么。现在我正在查看一些chrome扩展的例子,我看到这个“模式”非常多。
var Main = {
enable: function(){ window.addEventListener('mousemove', onMouseMove, false); },
onMouseMove: function(event){ _onMouseMove(event) },
_onMouseMove: function(event){
...lenghty implementation...
}
}
我的问题是,为什么?这是某种优化吗?
答案 0 :(得分:3)
你的问题有点模糊;但我猜你在问为什么开发人员有两种onMouseMove
方法,而不只是在一种方法中完成所有工作,即:
var Main = {
onMouseMove: function(event) {
// Why not just have the implementation here?
// Why are we delegating it to the other method?
_onMouseMove(event)
},
_onMouseMove: function(event){
// ...length implementation...
}
}
答案是因为scope is handled in JavaScript的原因。简而言之,大多数经典OOP语言中的this
关键字(如Java)总是引用函数范围内的父类(Main
) - JavaScript不能像这样工作。
由于JavaScript中没有经典类,this
关键字实际上是指调用它的函数;这就是new
关键字在通过构造函数创建新对象时产生这种差异的原因;例如:
function MyConstructor = function () {
// Assign a member property
this.aProperty = "An Example";
}
// Using the new keyword; a new scope is created for the call which refers to the
// object about to be created (and returned).
var withNew = new MyConstructor();
console.log(withNew.aProperty); // 'An Example'
// Without the new keyword...
var withoutNew = MyConstructor();
console.log(withoutNew.aProperty); // undefined
// Because we didn't use new, the calling function scope was applied, so
// the `this` keyword resolves caller's scope.
console.log(this.aProperty) // 'An Example'
通过从onMouseMove
委派给_onMouseMove
,范围仍然绑定到Main
对象,而不是绑定到触发鼠标事件的对象。实现此目的的另一种更易读的方法是使用委托,或者如果您使用的是ES5,Function.bind
var Main = {
enable: function() {
window.addEventListener('mousemove', onMouseMove.bind(this), false);
},
onMouseMove: function(event) {
// ...lengthy implementation...
}
}
答案 1 :(得分:1)
我不熟悉chrome扩展的实现方式,但是当我使用这种模式时,它专门用于保护我的实现。
通常,您的插件会公开某些属性和功能。该功能的用户可以轻松(甚至意外地)覆盖您的暴露功能。在这种情况下,如果你在该函数中有实际的实现,它就消失了。
更新:现在你已经更新了问题......
我个人认为将onMouseMove
以及_onMouseMove
作为对象的一部分暴露并没有多大价值。我已经看到一些这样编写的javascript库基于一些假设,即人们将“遵守约定”并将以_
为前缀的属性视为私有。
也许,我会做这样的事情:
var Main = function(){
var _onMouseMove = function(event){ ... do stuff...};
return {
enable: function(){...},
onMouseMove: _onMouseMove
}
}
答案 2 :(得分:1)
不,这不是任何优化(至少据我所知)。
我对chrome扩展没有太多了解,有时只读一些代码,没什么大不了的。但正如Brightgarden所说,你所询问的模式是保护实施。在其他语言中,您有内置的机制来封装私有数据。不是在js。这大致,非常粗略,在我看来是一种模块模式 - 其中的例子已经在brightgarden的答案中给出。您可以在此处阅读有关js中实现的设计模式的更多信息:http://addyosmani.com/resources/essentialjsdesignpatterns/book/
具体来说:http://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript 对于模块模式
实际模块模式比您的示例更好,更少混淆。
答案 3 :(得分:0)
除了让读者感到困惑之外,“模式”没有任何好处。