使用“窗口”,“文档”和“未定义”作为匿名函数的参数是一个包装了jQuery插件(Using 

2019-08-19 04:36发布

老实说,我不知道如何使标题更短。

我学会了如何通过研究源写一个jQuery插件SlidesJS插件。 当我遇到一些新的东西,我刚才问我的好朋友谷歌和大部分的时间,得到了满意的答复。 老实说,虽然,我从来没有做很大的努力。 我所知道的是, $是(可能)的简写jQuery对象的构造和$()jQuery()是提供jQuery的一样的东西是包括在内。

但最近,我试图了解背后的jQuery科学和如何写一个很好的 jQuery插件。 我遇到了一个很好的文章中,作者列出了几个模板创建一个jQuery插件。 由于其余均太复杂,我明白了,我喜欢的第一个: 一个轻量级的开始 。 现在,这里是上述模板的代码。

/*!
 * jQuery lightweight plugin boilerplate
 * Original author: @ajpiano
 * Further changes, comments: @addyosmani
 * Licensed under the MIT license
 */


// the semi-colon before the function invocation is a safety 
// net against concatenated scripts and/or other plugins 
// that are not closed properly.
;(function ( $, window, document, undefined ) {

    // undefined is used here as the undefined global 
    // variable in ECMAScript 3 and is mutable (i.e. it can 
    // be changed by someone else). undefined isn't really 
    // being passed in so we can ensure that its value is 
    // truly undefined. In ES5, undefined can no longer be 
    // modified.

    // window and document are passed through as local 
    // variables rather than as globals, because this (slightly) 
    // quickens the resolution process and can be more 
    // efficiently minified (especially when both are 
    // regularly referenced in your plugin).

    // Create the defaults once
    var pluginName = 'defaultPluginName',
        defaults = {
            propertyName: "value"
        };

    // The actual plugin constructor
    function Plugin( element, options ) {
        this.element = element;

        // jQuery has an extend method that merges the 
        // contents of two or more objects, storing the 
        // result in the first object. The first object 
        // is generally empty because we don't want to alter 
        // the default options for future instances of the plugin
        this.options = $.extend( {}, defaults, options) ;

        this._defaults = defaults;
        this._name = pluginName;

        this.init();
    }

    Plugin.prototype.init = function () {
        // Place initialization logic here
        // You already have access to the DOM element and
        // the options via the instance, e.g. this.element 
        // and this.options
    };

    // A really lightweight plugin wrapper around the constructor, 
    // preventing against multiple instantiations
    $.fn[pluginName] = function ( options ) {
        return this.each(function () {
            if (!$.data(this, 'plugin_' + pluginName)) {
                $.data(this, 'plugin_' + pluginName, 
                new Plugin( this, options ));
            }
        });
    }

})( jQuery, window, document );

我已经包括了意见,以便参考他们在我的问题。

我为什么不成熟的思想windowdocument已经包含在包装插件匿名函数的自变量(我不知道还能怎么称呼它),因为它是在评论因为它八九不离十有点儿缩短了执行时间。 但如何运作的? 上述匿名函数包裹插件的任何参数被传递到哪里? 以及如何在这些插件解决?

通常情况下,我会做$(window).resize(function(){})但是,这并不在这种情况下工作。 如果我做console.log(window)的插件功能里面,它说“未定义”。

这使我想到另一个问题是:什么是未定义 ? 是不是分配给未在范围所限定的对象数据类型 ? 怎么能作为参数传递? 不要参数必须是对象? 还有在评论中写这几行,但我不明白一个字:< 因此我们可以保证它的价值是不确定的真正 > whaaa?

总结一下:

  • 什么确实是指function($)
  • 我为什么要包括windowdocumentundefined作为自变量function($)
  • 如果我这样做,我怎么访问实际的windowdocument对象?
  • undefined是什么,为什么?

请宽容我。 我从来没有学过编程语言作为书面申请的明确目的的主题。 我研究了基本的C编写面向硬件的低级别例程微小核心的微控制器,这只是它。 我也学会对我自己的C ++广泛和一点的Java。 只是让你知道会发生什么。

Answer 1:

当你写一个函数,如:

(function (foo, bar) {
    return foo.getElementById(bar);
})(document, "myElement")

那么函数立即调用参数document"myElement"的参数foobar 。 因此,在函数内部, foo.getElementById(bar)等效于document.getElementById("myElement")

同样,在你的插件例子,你立即调用与参数的函数jQuery, document, window

什么确实是指function($)

$仅仅代表一个参考jQuery是到包装函数传递的对象。 后来,当匿名函数调用(jQuery, window, document) ,在$函数内部参考引用jQuery对象。 这样做是为了一些原因,而不是其中最重要的是,做$更快打字。 它还允许在包装以应用插件的特定实例的用户jQuery ,或许通过生产jQuery.noConflict()

我为什么要包括windowdocumentundefined作为自变量function($)

你并不需要包括这些。 原作者的理由是分配函数的局部变量引用这些都会缩短它需要解决这些变量的时间。 我断言,储蓄可以忽略不计; 我个人不会理会,除非我用了很多参考的window和/或document

至于undefined ,原作者在包括这个目的是确保有人没有改变undefined全局变量的EcmaScript 4(编辑:实际上ECMAScript的3 - 4版没有把它)或更早版本。 同样,我无法想象这个问题此起彼伏。 如果你真的担心这可能是一个问题,刚才在您的函数是这样的:

if(typeof undefined !== "undefined") {
    undefined = void 0;
}

如果我这样做,我怎么访问实际的windowdocument对象?

所有你需要做的是确保你的匿名函数结束时,函数调用传递的实际(jQuery的,窗口,文件)的参数。 或者,不包括windowdocument在你的函数签名的参数。 无论哪种方式,你会被引用的实际对象,无论间接的水平。

undefined是什么,为什么?

undefined的类型是“不确定”的全局变量。 那些没有被初始化的字段是完全相等(===)来定义。 它允许程序员故意空值和一个简单的初始化一个区分。 在ECMAScript中5及更高版本, undefined是只读的。 在此之前,有可能是其他的代码可以修改的值undefined 。 你总是可以得到真正的价值undefined与表达void 0 ...在myUndefinedVar = void 0;



Answer 2:

何谓function($)

传递$作为参数传递给你的功能可以让你使用jQuery速记对象,其中,因为你清楚地确定,只是一个别名jQuery对象(也看一看jQuery.noConflict()

我为什么要包括windowdocumentundefined作为自变量function($) 我为什么窗口和文档已经包含在包装插件匿名函数的参数粗的想法(我不知道还能怎么称呼它),因为它是在评论因为它八九不离十有点儿缩短了执行时间。 但如何运作的? 上述匿名函数包裹插件的任何参数被传递到哪里?

通过windowdocument的局部变量还挺缩短了执行时间 ,因为它更容易和更快地访问本地变量比全局变量,因为局部变量是第一链 。 哪种类型的回答你的第二个问题:创建一个封闭:论点得到了匿名函数的范围 ,这是你整点使得一个匿名函数里面反正过去了。

这些参数都在你的功能,在这里你看到的最后一个括号年底通过。 变量window在关闭是指global window ,因为你在年底顺利通过了。

为什么你传递的原因undefined是因为undefined是一个Javascript混乱的烂摊子。 基本上, undefined全局对象的属性 ,即,它是一个变量,一个它是不受保护的 ,这意味着可以被覆盖。 这意味着你可以有一个undefined这实际上是定义。

通过传递undefined你确保,即使任何人弄乱undefined在全球范围内(永远不要相信在全球范围内!:)),你仍然可以得到一个正确的undefined

此外,相同性能的原因适用于undefined

如果我这样做,我怎么访问实际的窗口和文档对象?

您已经访问它们,因为你将它们传递给你的函数。 正因为如此,你可以操纵它们。



Answer 3:

详细回答之前,让我注意,与其他编程语言,JavaScript是一个有点古怪的原因有两个:第一,它是创造了急速这意味着很多事情没有得到细化或落实到位。 其次,它是通过互联网非常迅速通过和微软很快很准确复制的语言(包括在语言中的错误)。 这样做的结果是,试图纠正在语言的设计错误是很难和/或不可能的,因为他们不希望打破现有网站的兼容性。

我们详谈:

的确什么是功能意味着($)

没什么特别的。 在javascript函数和变量名被允许使用字母az包括大小写,数字0-9和符号$_ 。 还有他们如何使用没有其他限制。 尽管有准则和公约,一些由语言规范本身所提到的,一些成长与编程社区。

因此, $是一个变量名。 有没有什么区别:

function foo ($) {alert($)}

function foo (x) {alert(x)}

这只是选择的参数名称。 然而,规范有力地表明, $不应该由人类编写的代码中使用。 这是确定的计算机生成的代码(A CoffeeScript的编译器为例),但不能确定为定期的脚本。 在另一方面,它是在使用jQuery的脚本强烈建议$总是引用jQuery对象(这亦恰好也是一个功能,那就是在javascript罚款,因为函数是对象)。

既然你写的jQuery的含义function ($)是接受一个参数的匿名功能,它预计该参数是一个jQuery对象。

我为什么要包括窗口,文件和未定义的函数($)的论点?

可以说,在JavaScript中的设计错误之一是缺乏的常量和/或不可改变/受保护的变量/对象的支持。 因此, windowdocumentundefined ,实际上正规的全局变量-任何人都可以重新分配给什么。

以下是疯了,但有效的JavaScript代码:

window = 42;

任何有理智的程序员会做这一点,但它可能没有少。 jQuery的开发者的话非常关注,因此jQuery的会尽可能真实的传递windowdocumentundefined进入插件的情况下,任何人都够疯狂去做疯狂的事情。

其中的的JavaScript的功能是函数参数覆盖全局变量。 因此,如果上述任何变量都被其他人劫持,他们将重新分配到功能的专有名词。

如果我这样做,我怎么访问实际的窗口和文档对象?

我们希望你传递正确的windowdocumentundefined的命名参数windowdocumentundefined到函数。 做其他事情意味着你不再访问该windowdocumentundefined对象。

有疯狂的解决方法,你可以做尝试去抓住的保持window对象(也称为全局对象),并从那里你可以得到保持document 。 jQuery的代码实际上是一个解决办法找回undefined的情况下,它已被劫持。

不确定的是什么,为什么?

当你正确地指出。 undefined是JavaScript的给予该声明,但没有分配给它们的值东西的价值。 但在JavaScript中undefined仅仅是一个全局变量。 如果你不碰它它最初具有的价值undefined (循环逻辑,我知道)。 但它可以被修改:

undefined = 'boom!';

从今以后所有的不确定变量都会有值"boom!" 。 JavaScript语言的最新规范实际上不允许重新分配到未定义的,但今天只有Safari浏览器做到这一点。

同样,任何理智的程序员会做到这一点。



Answer 4:

在参数列表中的标识符的夹杂物是有效的一样声明变量函数体,例如

function bar(foo) {
}

相当于

function bar(foo) {
  var foo;
}

但当然,你只是做第一,如果你想传递一个值到foo中

这样做的主要理由:

(function($) {
    // use $ here instead of jQuery
}(jQuery));

是jQuery的发布时,的Prototype.js已经使用“$”作为了一段时间,其主要功能标识被。 上述模式允许jQuery和prototype.js中在同一页面中使用,使用“$”作为不同的东西的标识符。

文件窗口传球,充其量,微优化有什么好处。 它提供了对他们没有保护被分配不同的值比预期的。 只是不要打扰和使用窗口文档的功能全局标识符内。

包括在参数不确定的 ,而不是通过它的数值是确保未定义真的是不确定的,就好像一个值意外通过它仍然可以影响一个明智的方式。 一个更安全的方法是:

(function() {
    var undefined;
    ...
}());

现在你确信 未定义在函数的范围实在是不明确的。 或者,如果你想要一个任务:

(function() {
    var undefined = void 0;
    ...
}());

但是,这仅仅是额外的输入。



文章来源: Using 'window', 'document' and 'undefined' as arguments in anonymous function that wraps a jQuery plugin