10

这种模式的一个缺点是,如果一个私有函数引用一个公共函数,那么如果需要补丁,这个公共函数就不能被覆盖。这是因为私有函数将继续引用私有实现,并且该模式不适用于公共成员,仅适用于函数。

有没有人举例说明他的意思?

链接到上面提到的显示模块模式

4

3 回答 3

14

将使用对象文字创建的对象与显示模块模式创建的对象进行比较。

这是一个作为对象文字创建的。

function makeGreeter(name){
  return {
    getName: function(){ return name;},
    sayHello: function(){console.log("Hello, " + this.getName());}
  }
}

var greeter = makeGreeter("Danny");
greeter.sayHello; // "Hello, Danny"
greeter.getName = function(){ return "George";}
greeter.sayHello(); // "Hello, George"

当您getName在返回的对象上覆盖公共方法时,sayHello所依赖的方法会getName获取更改。这是因为在 Object Literal 样式中,对公共函数的引用是通过this返回的对象进行的。

但是,当您使用显示模块模式时,

function makeGreeter(name){
  var getName = function(){ return name;},
    sayHello = function(){console.log("Hello, " + getName());};
  return {
    getName: getName,
    sayHello: sayHello
  }
}

var greeter = makeGreeter("Danny");
greeter.sayHello; // "Hello, Danny"
greeter.getName = function(){ return "George";}
greeter.sayHello(); // "Hello, Danny"

RMP 迎宾程序不会选择公共getName方法的覆盖。这是因为当 RMP 函数引用其他函数(公共和私有)时,它们引用的是私有闭包副本,而不是附加到返回对象的公共函数。

正是出于这个原因,我将显示模块模式视为一种反模式。

于 2014-02-21T10:40:19.987 回答
1

我会绑定getName到这个,它似乎指向 RMP 中返回的内容。

function makeGreeter(name){
    this.getName = function(){ return name;};
    var _sayHello = function(){console.log("Hello, " + this.getName());};
    return {
            getName: getName,
            sayHello: _sayHello
    }
}

不过,我更喜欢这个:

function makeGreeter(name){
    this.getName = function(){ return name;};
    var _sayHello = function(){console.log("Hello, " + this.getName());};
    var API = {
        getName: getName,
        sayHello: _sayHello
    };
    return API;
}
于 2015-02-23T14:18:08.577 回答
1

@I-Lin Kuo 给出的答案看起来不错,但在一种情况下会造成混乱。

function makeGreeter(name) {
return {
    getName: function() {
        return name;
    },
    sayHello: function() {
        console.log("Hello," + this.getName());
    }
  }
}

var greeter = makeGreeter("Danny");
greeter.sayHello(); //"Hello,Danny"
greeter.getName = function() {
    return "George";
}
greeter.sayHello(); //"Hello,George"

而不是greeter.sayHello它应该是greeter.sayHello()。造成很多混乱。

于 2018-05-15T15:07:12.727 回答