0

我有以下代码示例:

Application.Polyfills.prototype.prettifyCode = function(enable, js_lib, css_lib) {
    return Modernizr.load([{
        test : enable,
        yep : [ css_lib, js_lib ],
        complete: function() {
            return window.prettyPrint && prettyPrint();
        }
    }]);
};

如果我做一个console.log(typeof this.prettifyCode),其中this指的是Application.Polyfills,我得到function,但如果我做了console.log(typeof this.prettifyCode())我得到undefined。有人能告诉我为什么会这样吗?我该如何解决它,以便在两种情况下得到相同的结果,因为大多数时候函数需要参数,所以我需要使用括号?

更具体地说,我有一个方法:

Application.Polyfills.prototype.callPolyfills = function(array) {
    for (var i = array.length - 1; i >= 0; i--) {
        console.log(typeof array[i]);
        (typeof array[i] === "function") ? array[i].apply(this, [ this ]) : console.log('Index [' + i + ']: Invalid [ Function Required ]') ;
    };
};

上面的方法用于调用我放置在数组中的所有函数,如下所示:

this.callPolyfills([
        self.polyfillize([
            {
                test : [Modernizr.localstorage, Modernizr.sessionstorage],
                polyfill : [self.polyfills_url.storage_polyfill_url]
            },
            {
                test : [Modernizr.json],
                polyfill : [self.polyfills_url.json_polyfill_url]
            }
        ]),
        self.prettifyCode(self.prettify, self.libraries_url.google_code_prettyfier.css, self.libraries_url.google_code_prettyfier.js),
        self.consoleAvoidError()
    ]);

对其中的所有未知变量进行抽象,我想看看我在该数组中调用的内容是否实际上是一个函数,因为我现在已经在尝试检查该callPolyfills方法。但它失败了,因为它undefined每次都返回,即使它是一个函数。

4

3 回答 3

4

typeof this.prettifyCode()正在检查返回值的类型this.prettifyCode();这是undefined

typeof this.prettifyCode但是,正在检查prettifyCode成员的类型是什么this;这是一个function

您不应该希望这些相同。它们可能相同的唯一方法是返回一个函数,但两者和都将是this.prettifyCode这一事实毫无意义。typeof this.prettifyCode()typeof this.prettifyCodefunction

于 2013-01-06T14:47:09.407 回答
1

将此添加为新答案,因为这两个答案根本不相关


你的功能callPolyfills是正确的;这就是您要传递callPolyfills的问题(您传递的是您不想调用的函数的结果数组,而不是函数本身)。

function foo() {
    return "hi";
};

var bar = foo; // stores a reference to the function foo in `bar`, but doesn't call foo.
var baz = foo(); // calls foo and stores the result of the function ("hi") in baz.

你在做什么(除了令人困惑的论点之外,还有)selfthis

callPolyfills([
    foo(),
    foo(),
    foo()
]);

...即callPolyfills多次说“嗨”,但实际上并没有传递你想要的东西。

你应该通过的是;

callPolyfills([
    foo,
    foo,
    foo
]);

但是,这会阻止您为函数指定参数;在这种情况下,最简单的方法是将这些函数包装在匿名函数中。

this.callPolyfills([
  function () { 
    self.polyfillize([{
      test: [Modernizr.localstorage, Modernizr.sessionstorage],
      polyfill: [self.polyfills_url.storage_polyfill_url]
    }, {
      test: [Modernizr.json],
      polyfill: [self.polyfills_url.json_polyfill_url]
    }]);
  }, function () {
    self.prettifyCode(self.prettify, self.libraries_url.google_code_prettyfier.css, self.libraries_url.google_code_prettyfier.js);
  },
  self.consoleAvoidError
]);

...但是我不确定您真正获得了什么

于 2013-01-06T15:12:04.500 回答
1

也许不是在 callPolyfills 中显式调用你的 polyfill,你可以改变你的方法?像这样:

this.callPolyfills([
    [self.polyfillize, [
        {
            test : [Modernizr.localstorage, Modernizr.sessionstorage],
            polyfill : [self.polyfills_url.storage_polyfill_url]
        },
        {
            test : [Modernizr.json],
            polyfill : [self.polyfills_url.json_polyfill_url]
        }
    ]],
    [self.prettifyCodeself.prettify, self.libraries_url.google_code_prettyfier.css, self.libraries_url.google_code_prettyfier.js],
    self.consoleAvoidError
]);

那么你会像这样检查:

Application.Polyfills.prototype.callPolyfills = function(array) {
    for (var i = array.length - 1; i >= 0; i--) {
        if (typeof array[i] == "function") {
            // call with no arguments
            array[i].apply(this);
        }
        else if (typeof array[i].shift() == "function") {
            // call with arguments
            array[i].apply(this, array[i]);
        }
        else {
            // Invalid [ Function Required ]') ;
        }
    };
};
于 2013-01-06T15:15:13.393 回答