调用JavaScript函数时不带括号?

时间:2014-08-02 07:47:05

标签: javascript function

我正在编写一个API,我需要在一个" getter"中执行一个三元组。适用于各个领域。这很好但我不希望最终用户在访问这些字段时必须使用括号。

奇怪的是,当我访问字段而没有括号时,getter代码实际执行但是我想知道这对于javascript是否正常或者这是否依赖于浏览器?目前正在使用Firefox 31。

这有效:
var theScript = Scripts.jQuery_1_11_1_js(); // Note I'm using the parentheses

即使没有括号也可以使用。如何?:
var theScript = Scripts.jQuery_1_11_1_js; // Note the lack of parentheses

示例API:

var Scripts = (function () {
    function Scripts() {
    }
    Scripts.isProduction = false;
    Scripts.Url = "/Scripts";
    Scripts.jQuery_1_11_1_js = function () {
        return Scripts.isProduction ? Scripts.Url + "/jQuery_1_11_1.min.js" : Scripts.Url + "/jQuery_1_11_1.js";
    }
    return Scripts;
})();
var theScript = Scripts.jQuery_1_11_1_js();
var theScript = Scripts.jQuery_1_11_1_js; /// why does this work?

1 个答案:

答案 0 :(得分:4)

  

即使没有括号也可以使用。如何?

     

var theScript = Scripts.jQuery_1_11_1_js; // Note the lack of parentheses

不,它没有。该行执行得很好,但它没有调用 Scripts.jQuery_1_11_1_js,它只是将theScript的值设置为对函数Scripts.jQuery_1_11_1_js的引用。

只有两个 四个(从ES2015开始)我知道如何调用没有括号的函数:

  1. Scripts上的属性定义为ES5 getter。这是ES5的语法:

    Object.defineProperty(Scripts, "jQuery_1_11_1_js", {
        get: function() {
            return Scripts.isProduction ? Scripts.Url + "/jQuery_1_11_1.min.js" : Scripts.Url + "/jQuery_1_11_1.js";
        }
    });
    

    现在,行

    var theScript = Scripts.jQuery_1_11_1_js;
    

    ...将调用我们定义为该属性的getter的匿名函数。

    不幸的是,你can't do that in IE8。在IE8(奇怪)中,Object.defineProperty只能在DOM元素上创建属性,而不能在普通对象上创建属性。 IE9正确支持它。

  2. 为了完整起见,还有第二种方法,new

    var foo = new Foo;
    

    ......相当于

    var foo = new Foo();
    

    但是,当然,除非Foo是一个构造函数,否则你不想这样做,因为它会创建一个对象作为Foo传递给this

  3. 调用标记函数

    someFunction`template contents here`;
    

    这看起来不像函数调用,但它确实如此。它解析模板,评估任何标记表达式,并将模板的原始形式(具有添加的raw属性的字符串数组,标记替换的后续参数)传递到someFunction。而someFunction(`template contents here`)将评估模板,评估任何标记表达式,并将它们替换为生成字符串的模板,然后将字符串传递给someFunction。更多on MDN

  4. Proxy object上执行任何操作,因为所有基本对象操作(获取属性,设置属性,定义属性,获取原型等等)都可以陷阱代理,生成对陷阱处理程序的调用。