javascript - 是否可以在构造函数之外定义特权方法?

标签 javascript

好吧,我有一个带有一个 secret 和一种方法的构造函数:

function Keeper(get) {
    var secretPower = 'wisdom';

    this.get = get ? get : function () { 
        return 'Its secret power is: ' + secretPower; 
    }
    // now this is privileged method only in case that there are no arguments?
}

现在我将创建两个实例,一个具有特权方法...

var yourKeeper = new Keeper();
yourKeeper.get();       // "Its secret power is: wisdom"

...但另一个不同。它可以触及周围的上下文,但不能触及构造函数的私有(private)...

var myKeeper = new Keeper(function() { 
        return 'Its secret power is: ' + secretPower; 
    });
myKeeper.get();         // ReferenceError: secretPower is not defined

...这也不能按我想要的方式工作:

myKeeper.get = function() { 
    return 'Its secret power is: ' + secretPower; 
}
myKeeper.get();         // ReferenceError: secretPower is not defined

当然这是行不通的,因为在这些情况下 secretPower 是全局变量,所以:

var secretPower = 'none';
myKeeper.get();         // "Its secret power is: none"

那么是否可以在构造函数之外定义特权方法?如何实现?

可以用 eval 来完成吗?(我知道...这是邪恶的...我只是感兴趣)

最佳答案

是的,可以在构造函数之外定义特权方法。操作方法如下:

var Keeper = (function (key) {
    function Keeper(get) {
        var private = {
            secretPower: "wisdom"
        };

        this.getPrivate = function (k) {
            if (k === key) return private;
        };

        this.get = get || defaultGet;
    }

    function defaultGet() {
        var private = this.getPrivate(key);
        return "The secret power is: " + private.secretPower;
    }

    return Keeper;
}({}));

其工作原理如下:

  1. 我们通过创建 Immediately Invoked Function Expression (IIFE) 来创建命名空间.
  2. 我们创建一个名为key的对象。该对象对于我们刚刚创建的命名空间来说是私有(private)的。因此只有特权函数和构造函数才能访问它。
  3. 在构造函数内,我们创建一个名为 private 的对象,它保存每个实例的私有(private)状态。
  4. 我们还创建了一个名为 getPrivate 的特权方法,它接受参数 k,并且仅在 k 时才返回私有(private)对象key 我们在步骤 2 中创建。因此,只有特权函数才能访问私有(private)对象。
  5. 想要访问对象私有(private)状态的特权函数必须调用 getPrivate(key) 来获取私有(private)状态对象。

注意:只有当您有多个需要访问对象私有(private)状态的特权函数时,此方法才有用。此外,调用 getPrivate 会给特权函数带来(非常)小的性能开销。


顺便说一句,如果您想在 JavaScript 中编写干净的面向对象代码,请查看 augment图书馆。使用augment,上面的代码看起来像这样:

var Keeper = Object.augment(function (key) {
    this.constructor = function (get) {
        var private = {
            secretPower: "wisdom"
        };

        this.getPrivate = function (k) {
            if (k === key) return private;
        };

        this.get = get || defaultGet;
    };

    function defaultGet() {
        var private = this.getPrivate(key);
        return "The secret power is: " + private.secretPower;
    }
}, {});

关于javascript - 是否可以在构造函数之外定义特权方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17300577/

相关文章:

javascript - cometd 消息发送两次

javascript - 我的 api 调用在 javascript 中不起作用,但在 postman 和浏览器中工作正常

javascript - 在导航栏悬停时更改 div 的背景图像

javascript - 带有 proxytable 和 websockets 的 Node http 代理

javascript - 重复调用命中 php 文件的函数

javascript - 如何在对象数组中找到所有具有 ID 的记录?

javascript - 美国队长与 svg

javascript - 从 data-* 属性获取计数不起作用,为什么?

javascript - 根据用户帐户隐藏菜单项

javascript - 在javascript中查找特定单词(正则表达式)中的字符类型