2

我从来没有真正使用过 JavaScript,但我大致知道它是关于什么的。现在我正在浏览一些 chrome 扩展的例子,我看到了很多这种“模式”。

var Main = {
    enable: function(){ window.addEventListener('mousemove', onMouseMove, false); },
    onMouseMove: function(event){ _onMouseMove(event) },
    _onMouseMove: function(event){
        ...lenghty implementation...
    }
}

我的问题是,为什么?这是某种优化吗?

4

4 回答 4

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...
    }
}

答案是因为JavaScript 是如何处理范围的。简而言之,this大多数经典 OOP 语言(如 Java)中的键始终是指MainFunction 范围内的父类 ( ) - 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'

通过委派 fromonMouseMove_onMouseMove范围,仍然绑定到Main对象,而不是绑定到触发鼠标事件的对象。另一种更易读的方法是使用委托,或者如果你使用的是 ES5,Function.bind

var Main = {
    enable: function() {
        window.addEventListener('mousemove', onMouseMove.bind(this), false); 
    },
    onMouseMove: function(event) { 
        // ...lengthy implementation...
    }
}
于 2012-05-06T17:51:20.283 回答
1

我不熟悉 chrome 扩展的一般实现方式,但是当我使用这种模式时,它专门用于保护我的实现。

通常,您的插件会公开某些属性和功能。该功能的用户可以轻松(甚至意外地)覆盖您公开的功能。在这种情况下,如果您在该函数中有实际实现,它就消失了。

更新:现在您已经更新了问题...

onMouseMove我个人认为暴露对象的一部分和作为对象没有多大价值_onMouseMove。我已经看到一些这样编写的 javascript 库是基于人们会“遵守约定”并将前缀_为私有的属性的假设。

可能,我会做这样的事情:

var Main = function(){
   var _onMouseMove = function(event){ ... do stuff...};
   return {
       enable: function(){...},
       onMouseMove: _onMouseMove
   }
}
于 2012-05-06T17:25:47.517 回答
1

不,这不是任何优化(至少据我所知)。

我对chrome扩展了解不多,只是偶尔读一些代码,没什么大不了的。但是,正如 Brightgarden 所说,您所询问的模式是为了保护实施。在其他语言中,您具有用于封装私有数据的内置机制。不在js中。在我看来,这粗略,非常粗略,似乎是一种模块模式-brightgarden 的答案中已经给出了其中的示例。您可能想在这里阅读更多关于在 js 中实现的设计模式:http: //addyosmani.com/resources/essentialjsdesignpatterns/book/

具体在这里:http ://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript 模块模式

实际的模块模式比您的示例更好且更容易混淆。

于 2012-05-06T17:41:23.720 回答
0

除了让读者感到困惑之外,这种“模式”没有任何好处。

于 2012-05-06T17:39:27.210 回答