JavaScript 中怎么不带括号的调用函数

2,364 阅读1分钟
原文链接: segmentfault.com

(1)作为构造器调用

利用new关键字可以不带括号地调用函数:


function Greet() {

    console.log('hello');

}

new Greet; // parentheses are optional in this construct.

new操作符的语法为:


new constructor[([arguments])]

(2)隐性实现 toString 或者 valueOf 的调用

另一个例子就可以隐性调用toString或者valueOf方法:


var greet = {

    toString: function() {

         return 'hello';

    }

}



greet + ''; // 字符串连接会强制性转化到String类型,这样就隐性调用了toString

可以利用这种方式调用任意的函数:


function func() {

    console.log('hello');

}



var greet = {

    toString: func

}



greet + '';

或者使用 valueOf:


function func() {

    console.log('hello');

}



var greet = {

    valueOf: func

}



+greet;

如果要使用valueOf的话,可以在Function的原型中完成复写,这样也能完成一个函数的传递:


Function.prototype.valueOf = function() {

    this.call(this);

    // Optional improvement: avoid `NaN` issues when used in expressions.

    return 0; 

};

function greet() {

    console.log('hello');

}



+greet;

(3)Iterators

可以利用*操作符创建一个迭代器,然后在下一个元素被遍历的时候就会被自动调用了:


function* func() {

    console.log('hello');

}



var greet = {};

greet[Symbol.iterator] = func;



[...greet];

一般来说用迭代器的时候都会附带一个yield语句,但是在这边希望调用某个函数的时候不一定要加上这个语句。上述代码中是最后一个语句调用了函数,同时也可以利用解构赋值来进行调用


[,] = greet;

或者使用for ... of结构:


for ({} of greet);

(4)Getters


function func() {

    console.log('hello');

}



Object.defineProperty(window, 'greet', { get: func });



greet;

也可以利用Object.assign:


Object.assign(window, { get greet() {

    console.log('hello');

); 

greet;

全局将 window 对象替换成一个你自定义的全局对象。

(5)Tagged Template Literals

ES6中可以利用模板字符串的方式调用:


function greet() {

    console.log('hello');

}



greet``;