3

作为禁用功能的一种有点 hacky 的方法,我想出了使用这样的一些 javascript 的想法:

//fakefrob.js
var frob = function () {
    return {
        myFunc: function(){},
        myFunc1: function(){},
        myFunc2: function(){return 2;},
        myFunc3: function(){},
        myFunc4: function(){}
    };
}();

在这个例子中,真正的 frob 具有这些功能的实现。显然这是一个 hack(这些函数大多什么都不做或有占位符返回值)。如果我将 foobar 添加到 realfrob.js,我必须将 foobar 的空实现添加到 fakefrob.js。有没有办法(理想情况下不使用库)来编写 fakefrob.js,使得frob.foobarfoobar 的行为被定义为function(){};,而不实际将 foobar 添加到 fakefrob.js?

4

2 回答 2

7

有没有办法(理想情况下不使用库)来编写 fakefrob.js,使得frob.foobarfoobar 的行为被定义为function(){};,而不实际将 foobar 添加到 fakefrob.js?

你的意思是,一个包罗万象的属性,映射到一个无操作函数?不,JavaScript(目前)根本没有包罗万象的属性。(我相信他们正在考虑一些机制作为在某个阶段出现的代理内容的一部分。)

但是,如果您可以访问frob代码中的真实值,fakefrob则可以完全自动生成:

// Assumes `frob` already exists
(function() {
    var mock;
    var name;

    // Build the mock, with a function for each function
    // on the real object.
    mock = {};
    for (name in frob) {
        if (typeof frob[name] === "function") {
            mock[name] = function() { };
        }
    }

    // Replace the original    
    frob = mock;
})();

当然,如果你想复制非函数属性,你可以同时这样做。

请注意,我故意没有包含hasOwnProperty上面的循环中,因为我假设您希望您的模拟包含函数,即使frob它们是从原型继承的。

如果frob继承了一些函数并且你希望你的 mock 对hasOwnPropety它们表现出与原始 frob 相同的行为,你可以获得更多创意:

// Assumes `frob` already exists
(function() {
    var mock;
    var mockProto;
    var name;

    function FakeFrob() {
    }

    mockProto = FakeFrob.prototype;

    // Build the mock, with a function for each function
    // on the real object.
    mock = new FakeFrob();
    for (name in frob) {
        if (typeof frob[name] === "function") {
            if (frob.hasOwnProperty(name)) {
                mock[name] = function() { };
            }
            else {
                mockProto[name] = function() { };
            }
        }
    }

    // Replace the original    
    frob = mock;
})();

现在,如果原件frob有自己的foo( frob.hasOwnProperty("foo")is true) 但继承的bar( frob.hasOwnProperty("bar")is false),hasOwnProperty那么在您的模拟中会说完全相同的事情。

于 2012-07-03T15:19:57.363 回答
1

正如TJ Crowder 建议的那样, 受支持的浏览器可以使用代理对象来完成此操作:

var frob = new Proxy({}, {get: function(){return function(){}}})

这是如何工作的:
这将创建一个代理,它拦截所有属性获取器,将结果替换为一个空函数。通常,代理对象用于拦截并最终将调用转发到我们的目标(这里,目标是{})。但是,这段代码盲目地返回一个空函数,完全忽略了目标。

于 2018-01-05T16:25:57.500 回答