2015-04-16 40 views
16

我发现它here这是什么javascript表示法?

;(function ($, window, document, undefined) { 
//code 
}(jQuery, this, this.document)); 

这是我第一次看到这样的事情。它是什么以及它是如何解释的?我不明白为什么它必须通过this和this.document,以及'undefined'的含义。

的原因,我问的是,因为我把它在我的网页和

if($('ul.mtree').length) 

返回false,尽管当我在控制台中键入它返回true。

+1

@ ZachLeighton,这个问题有点令人困惑,但我认为乔治询问关于jquery文件加载的问题 –

+0

我不明白为什么它必须通过this和this.document,以及'undefined' –

+0

@NathanKoop很好抓,我很快看了一眼,看到了分号就是这样。 –

回答

16

第一个分号;除了可能忘记分号的其他代码外,还设置了以下代码。这是非常重要的,因为如果没有找到分号,那么这些元素会尝试运行前面的语句作为函数。

对于其余的代码,我们只是声明一个“内联”函数,将立即执行,其中参数$, window, document然后从全局范围实例化为jQuery, this, this.document(分别)。这主要是为了让您可以在新的jQuery插件中使用“$”而不用担心$是否被其他地方覆盖。您可以确定$jQuery相同。

了解更多关于从OP“保护$别名和添加范围” here

更新:

对于if语句返回false,请确保您的HTML是在调用的时候加载您的if声明。一个快速的方法来做到这一点,是它包装在一个$(document).ready方法,像这样:

$(document).ready(function() { 
    if($('ul.mtree').length) { 
     alert("got 'em!"); 
    } 
}); 
+1

只需要提一下:它对于js代码的缩小很有帮助。 –

+0

是的!好点@RoyiNamir –

+1

另外:你忘了提到undefined可能被用户代码覆盖(我不认为现在是这种情况),但是最好不向变量发送任何东西,所以你可以肯定它有'undefined '价值 –

3

这是一个立即执行的功能。 The;在开始时,可​​以防止缩小后的潜在语法错误。

函数本身提供参数的范围,而不是在全局范围内引用它们。它还提供了使用该函数定义的局部变量的隐私。通过undefined传递的最终参数有点令人困惑,它可以防止在全局范围内对未定义表示的恶意更改。

如果你是谷歌的JavaScript条款,如自执行功能,全局范围,闭包,模块模式可用的资源很多。

+0

关于“undefined”的好电话。我错过了。 –

1

或许,该代码是应该固定在其中$windowdocument已阴影与其他值的情况下:

(function() { 
var window = 123, 
    document = 'abc', 
    $ = Function.prototype; 
})(); 

然后,

  • $jQuery使用的速记和其他图书馆。该代码假定jQuery未被其他事物遮蔽,因此它会创建一个名为$的变量,其值为jQuery
  • this是一个关键字。如果未以非严格模式显式设置,则它将成为全局对象。所以你的代码创建了一个带有该值的局部变量window。请注意,这是危险的,因为this可能已设置为某个值,或者在严格模式下为undefined
  • 假设this是全局对象,this.document将是文档对象。
  • undefined是全局对象的一个​​属性,它没有ECMAScript 3中的ReadOnly属性,所以它可以被覆盖。你的代码创建一个局部变量而不分配任何值,所以它变成了真正的未定义的。这是ECMAScript 5以来不再需要的,因为window.undefined的[[Configurable]]和[[Writable]]属性设置为false

然后,

(function() { 
var window = 123, 
    document = 'abc', 
    $ = Function.prototype; 
    (function($, window, document, undefined) { 
     // `$`, `window`, `document` and `undefined` have been restored 
    })(jQuery, this, this.document); 
})(); 
2

这可能会有帮助,包括你有不正常的代码的副本。

但是,为了回答关于为什么if($('ul.mtree').length)可以在控制台返回true的问题,但false页面可能取决于时机(例如函数执行的DOM加载之前)。当你加载控制台检查值时,DOM被加载并返回true。

请务必在页面末尾包含您的JS,或者仅在文档加载后调用。

+0

包含OP –

+0

好调用的“文档加载”语法可能会有所帮助,因为我不想对OP的代码做任何假设,所以我最初将其忽略掉了。我会编辑它,但看起来像您已经编辑你的答案,包括一个样本,所以我会离开我一个人来限制重复。 – MichaelM

1

如果我理解正确的话你的问题,符号;提前函数语句的功能,如

(function(){ 
    console.log('no name'); 
})(); 

(function(){ 
    console.log('no name') 
}()); 

-function(){ 
    console.log('no name'); 
}(); 

+function(){ 
    console.log('no name'); 
}(); 

~function(){ 
    console.log('no name'); 
}(); 

!function(){ 
    console.log('no name'); 
}(); 

你会看到的符号,如“()”,“ - ”,” +”, '〜', '!'

并且符号的功能是将函数语句解析成表达式并立即执行该函数!

但我建议你只用'()'来执行函数语句,因为它是例程中使用的正式方法和常规方法。