Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
238 views
in Technique[技术] by (71.8m points)

javascript - 调用没有括号的函数(Invoking a function without parentheses)

I was told today that it's possible to invoke a function without parentheses.(今天我被告知可以调用没有括号的函数。)

The only ways I could think of was using functions like apply or call .(我能想到的唯一方法是使用applycall类的功能。) f.apply(this); f.call(this); But these require parentheses on apply and call leaving us at square one.(但这些要求括号applycall我们留在第一方。) I also considered the idea of passing the function to some sort of event handler such as setTimeout :(我还考虑了将函数传递给某种事件处理程序(如setTimeout的想法:) setTimeout(f, 500); But then the question becomes "how do you invoke setTimeout without parentheses?"(但问题就变成了“如何在没有括号的情况下调用setTimeout ?”) So what's the solution to this riddle?(那么这个谜语的解决方案是什么?) How can you invoke a function in Javascript without using parentheses?(如何在不使用括号的情况下在Javascript中调用函数?)   ask by Mike Cluck translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are several different ways to call a function without parentheses.(调用没有括号的函数有几种不同的方法。)

Let's assume you have this function defined:(我们假设你定义了这个函数:) function greet() { console.log('hello'); } Then here follow some ways to call greet without parentheses:(然后在这里按照一些方法调用没有括号的greet :) 1. As Constructor(1.作为构造函数) With new you can invoke a function without parentheses:(使用new您可以调用没有括号的函数:) new greet; // parentheses are optional in this construct. From MDN on the new oprator :(来自MDN的new鸦片 :) Syntax(句法) new constructor[([arguments])] 2. As toString or valueOf Implementation(2.至于toStringvalueOf实现) toString and valueOf are special methods: they get called implicitly when a conversion is necessary:(toStringvalueOf是特殊方法:当需要转换时,它们会被隐式调用:) var obj = { toString: function() { return 'hello'; } } '' + obj; // concatenation forces cast to string and call to toString. You could (ab)use this pattern to call greet without parentheses:(您可以(ab)使用此模式在没有括号的情况下调用greet :) '' + { toString: greet }; Or with valueOf :(或者使用valueOf :) +{ valueOf: greet }; 2.b Overriding valueOf in Function Prototype(2.b在函数原型中覆盖valueOf) You could take the previous idea to override the valueOf method on the Function prototype :(您可以采用先前的想法覆盖Function原型上的valueOf方法:) Function.prototype.valueOf = function() { this.call(this); // Optional improvement: avoid `NaN` issues when used in expressions. return 0; }; Once you have done that, you can write:(完成后,您可以写:) +greet; And although there are parentheses involved down the line, the actual triggering invocation has no parentheses.(虽然在线下有括号,但实际的触发调用没有括号。) See more about this in the blog "Calling methods in JavaScript, without really calling them"(在博客“使用JavaScript调用方法,而不是真正调用它们”中查看更多相关信息) 3. As Generator(3.作为发电机) You could define a generator function (with * ), which returns an iterator .(您可以定义一个生成器函数 (带* ),它返回一个迭代器 。) You can call it using the spread syntax or with the for...of syntax.(您可以使用扩展语法for...of语法来调用它。) First we need a generator variant of the original greet function:(首先,我们需要原始greet函数的生成器变体:) function* greet_gen() { console.log('hello'); } And then we call it without parentheses:(然后我们称之为没有括号:) [...{ [Symbol.iterator]: greet_gen }]; Normally generators would have a yield keyword somewhere, but it is not needed for the function to get called.(通常,生成器会在某处具有yield关键字,但函数不需要调用它。) The last statement invokes the function, but that could also be done with destructuring :(最后一个语句调用该函数,但也可以通过解构来完成:) [,] = { [Symbol.iterator]: greet_gen }; or a for ... of construct, but it has parentheses of its own:(或者是for ... of构造,但它有自己的括号:) for ({} of { [Symbol.iterator]: greet_gen }); Note that you can do the above with the original greet function as well, but it will trigger an exception in the process, after greet has been executed (tested on FF and Chrome).(请注意,您也可以使用原始的greet函数执行上述操作,但是在执行greet (在FF和Chrome上测试) 之后 ,它将在进程中触发异常。) You could manage the exception with a try...catch block.(您可以使用try...catch块来管理异常。) 4. As Getter(作为Getter) @jehna1 has a full answer on this, so give him credit.(@ jehna1对此有完整的答案,所以给他信任。) Here is a way to call a function parentheses-less on the global scope, avoiding the deprecated __defineGetter__ method.(这是一种在全局范围调用函数括号的方法,避免使用已弃用的__defineGetter__方法。) It uses Object.defineProperty instead.(它使用Object.defineProperty代替。) We need to create a variant of the original greet function for this:(我们需要为此创建原始greet函数的变体:) Object.defineProperty(window, 'greet_get', { get: greet }); And then:(然后:) greet_get; Replace window with whatever your global object is.(用您的全局对象替换window 。) You could call the original greet function without leaving a trace on the global object like this:(您可以调用原始的greet函数,而不会像这样在全局对象上留下痕迹:) Object.defineProperty({}, 'greet', { get: greet }).greet; But one could argue we do have parentheses here (although they are not involved in the actual invocation).(但有人可能会说我们在这里有括号(虽然他们没有参与实际的调用)。) 5. As Tag Function(5.作为标记功能) With ES6 you can call a function passing it a template literal with this syntax:(使用ES6,您可以使用以下语法调用函数传递模板文字 :) greet``; See <a href="https://stackoom.com/link/aHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jc

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...