Possible Duplicate:
What does the exclamation mark do before the function?
我正在维护一个带有“tweet”按钮的现有网站,该按钮似乎来自 this page
这里的一位同事提出了一个很好的问题:为什么这个脚本标签会反转这个自调用函数的(undefined
通过没有返回语句)值? (为便于阅读而漂亮,原文在链接中)
<script>
!function(d,s,id) {
//^--- that
var js,fjs=d.getElementsByTagName(s)[0];
if(!d.getElementById(id)) {
js=d.createElement(s);
js.id=id;
js.src="https://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js,fjs);
}
}(document,"script","twitter-wjs");
</script>
在我非 JS 专业人士看来,这似乎是在翻转 undefined
的 bool 值。 ,从而允许整个 <script>
标签评估为真。对于它的值(value),这对我来说是一个完全陌生的想法(<script>
标签有一个表达式值)。
我的期望是有一些特定的浏览器可以使用 <script>
标签的 bool 值(是的,我什至觉得输入那个值很疯狂)很重要。
所以基本问题是:Does a <script>
对您知道的任何浏览器都有有意义的“表达”值?和在这种情况下,真与假的隐含含义是什么?
解释发生了什么以及为什么......
在 Javascript 中,您有函数语句
和函数表达式
。两者相似,但不完全相同。
函数声明
function myTest() {return true;}
函数表达式
var f = function() {return true;}
alert(f()); //
alert(function() { return true}); // Return value is used
// and even
(function(x, y) {
var z, x; // private variables, hidden from the outside scope
var r = x + y;
// Return value is ignored.
}(1, 2));
// The ! can be used to start a function expression too.
// This is totally legal Javascript, but it isn't in the normal
// "vernacular" of the langage
!function(x, y) {
var z, z1; // Private vars
// Do something with side effects
// Return value is ignored.
}(x, y);
因评论而更新
//The following code works identical:
var v1 = (function(a, b) {return a+b}(1,2));
var v2 = (function(a, b) {return a+b})(1,2);
var v3 = function(a, b) {return a+b}(1,2)
我更喜欢第一种形式,因为它让我可以在我的编辑器上使用 block 匹配工具,而 f1
形式是有时有用的程序的首选 JSLint和 JSHint .
所有人都创建一个函数表达式,然后立即调用它。在这种情况下,Javascript 编译器不需要括号,但它们对读者来说是一个非常有用的提示,表明这不是正常的赋值。
另一方面,你必须有东西来告诉JS引擎你有一个函数表达式而不是一个函数语句。上面的 =
符号有效,但是当没有赋值时,您需要从某种运算符开始,比如 (+!
!function(x, y) {alert(x, y)}(1, 2);
前导运算符使它成为一个表达式。上面示例中的 ()
也将其强制为表达式。