今天我发现可以在函数调用的括号之前使用操作。
E.g。
console.log|('Hello world!');
或
console.log>>(33);
为什么这可能会发生什么?
答案 0 :(得分:3)
喜欢大多数" algol-like"语言,括号在javascript中有多种含义:
2 * (3 + 4)
console.log(5)
function(x) {}
在函数名和函数调用括号之间插入运算符时,该运算符将成为分组运算符。它不再是一个函数调用了。所以func(args)
变成func op (args)
,这在语法上是一个有效的表达式,因为函数是"一等公民"在javascript中,可以像任何其他值一样在表达式中使用。它是否有意义是另一个问题,因为除了+
之外,运营商在应用于函数时不会产生任何有意义的东西。
答案 1 :(得分:1)
实际上,你没有执行这个函数,你只是在评估一个表达式(完全没有意义)
console.log|('Hello world!')
将被评估为:
[native function] | 'Hello world!'
这没有任何意义,因为" |"是一个按位运算符。与您提供的其他示例相同。
因此,您不是在函数调用之间放置运算符。您正在分离值,并且不再执行预期的操作(函数调用)。
答案 2 :(得分:1)
简单地说:因为操作符在操作数上工作,并且函数至少在JS中是第一类对象(意味着它们可以被传递,返回和操作)。
为此,您当然需要使用运营商。一个简单但不太牵强的例子:
function foo()
{
return foo.bar;//. is an operator
}
console.log(foo());//logs undefined
foo.bar = '123';//again, the . operator
console.log(foo());//logs 123
然而,在您的情况下,JS将评估两个操作数(运算符两侧的表达式):
console.log (LOperand)
| (operator)
('hello world') (ROperand, to be evaluated further still because of the grouping operator ())
尝试将它们评估为兼容类型,以便操作员完成其工作。 console.log
是一个对象,实际上是一个函数实例。 hello world
是分组运算符内的字符串常量
如何强制和评估这些类型在ECMAScript标准(google it)中指定,但底线,函数(console.log
)很可能被强制转换为字符串(就好像你打电话给{{ 1}},在铬上给出console.log.toString()
。结果是代码的行为与:
"function log() { [native code] }"
产生"function log() { [native code] }"|"Hello world"
答案 3 :(得分:1)
可以在函数调用的括号之前使用操作。
不太好,
console.log|('Hello world!');
相当于
console.log | 'Hello world!';
其含义与您的意图不同:)
('Hello world!')
与'Hello world!'
相同,而|
是JavaScript中的bitwise OR 运算符(left | right
将匹配左操作数和右操作数逐位)。
在您的示例中,console.log
没有括号会返回函数本身(而不是返回console.log()
的{{1}}),因此您基本上是{{1 }}