(function($){})(jQuery)资料记录

对于匿名函数大家应该比较熟悉,那么(function($){})(jQuery)就比较容易理解了. 就是写了一个匿名函数同时理解传递JQuery实参调用.

等同于:

  

var fn = function($){....};
fn(jQuery); 

这样的写法经常出现在各种jQuery插件中,其关键原因在于: jQuery插件很多,你无法保证自己的定义和使用变量/函数名称不会用于其它插件中,那么最好的办法就是让你自己的代码具有"封装性"那么局部变量和局部函数就是很好的解决办法,也就是将所有内容写入一个匿名函数中.

同时,由于基于jQuery的插件都要用到JQuery本身,就需要导入到匿名函数中.

说到这里就干脆将jQuery的关键点拿出来瞅瞅,若不是专业前端工程师看看这部分重点也就ok了.

以下内容来源"

看了这个才发现jQuery源代码不是那么晦涩

"

一些晦涩的操作符:

(function(){})();

几乎所有的开源js代码开篇都是这样(function(……){……})(……);

下面是Jquery的部分源码:

(function( window, undefined ) {
    var jQuery = function( selector, context ) {
        // The jQuery object is actually just the init constructor ‘enhanced‘
        return new jQuery.fn.init( selector, context );
    },

    // Map over jQuery in case of overwrite
    _jQuery = window.jQuery,

    // Map over the $ in case of overwrite
    _$ = window.$,
    ……
    indexOf = Array.prototype.indexOf;

    // Expose jQuery to the global object
    window.jQuery = window.$ = jQuery;
})(window);

那么这个操作符(function(){})();到底是什么意思呢?

(function(){})中的定义了一个function,紧接着的()表示立即执行这个function

我们看到Jquery源码第一个()中是定义了一个匿名function( window, undefined ) {};接着末尾有个(window),就表示执行这个匿名function,并传入参数window

在匿名function( window, undefined ) {}中,定义了一个局部变量jQuery;然后在末尾我们看到Jquery末尾有一句window.jQuery = window.$ = jQuery; 这句代码就表示,将此前定义的jQuery导出到window对象。这也是为什么我们可以在代码任何地方直接使用$ 、jQuery 对象,因为在这里已经将$ 、jQuery 对象挂载到window下去了,而window.$ 、window.jQuery 与直接使用$ 、jQuery 是没有区别的。

(注意,这个window对象是传入的参数window,而不是浏览器window对象!!一个形参、一个实参。我们可以在定义function的时候,将参数window取名为其他字符。所以我们看到jquery.min.js中这个匿名function变成了(function(E,B){})(window);)

通常(function(){})()用来封装一些私有成员或者公共成员的导出。

令人迷惑的","

我们知道 , 一般用于一次定义多个变量、定义多个参数等。像上面的jQuery源码中在var jQuery后面,使用,一次定义了很多个变量。 但是,像下面的代码,可能大家就不一定看得懂了:

//html:<input type="hidden" value="king" id="nameHide"/>
jQuery(document).ready(function() {
    var showName=function(){
        var value,nameInput=$("#nameHide");
        return nameInput.show(),value=nameInput.val();
    };
    alert(showName());
});
//结果:弹出king

这里的nameInput.show(),value=nameInput.val()中的,运算符的作用是返回,右侧表达式的值。所以,return 后面如果有多个表达式,且表达式之间由,隔开,整个return表达式返回的是最后一个,右侧的表达式的值。

,在开源代码中常常被用于return表达式中,以及跟下面我们要讲到的()运算符一起使用。

()广义上的代码包装

我们遇到复杂的逻辑表达式时,我们通常会把需要一起运算的表达式用“()”包起来:(a||b)&&(c||d)

其实,我们可以这样理解:()运算符将一个表达式包裹起来作为一个整体进行运算,然后返回这个整体的值。

那么上面的(function(){})()中左侧定义function的()也是这个作用,将这个function给包裹起来,然后返回这个function。我们调用方法一般是a();那么(function(){})的作用就是返回这个function对象,然后(function(){})()右侧的()表示调用这个function

我们再来看其他的用法:

//html:<input value="kings" id="name"/><div id="nameErrorTip">输入错误!</div>
jQuery(document).ready(function() {
    var nameValidate=function(){
        var value,nameInput=$("#name"),nameErrorTip=$("#nameErrorTip");
        return (value=nameInput.val(),value=="king")?(nameErrorTip.hide(),"对了,输入为king!"):(nameErrorTip.show(),"请输入king!");
    };
    alert(nameValidate());
});

//结果 nameErrorTip显示,弹出"请输入king!"
//html:<input value="king" id="name"/><div id="nameErrorTip">输入错误!</div>
//结果 nameErrorTip隐藏,弹出"对了,输入为king!"

这里(value=nameInput.val(),value=="king")()将里面的表达式作为一个整体进行运算,而里面的表达式又是由,构成的多个表达式组,所以执行的时候会把这多个表达式都执行一次,并且返回最后一个表达式的值!

所以 (value=nameInput.val(),value=="king")执行时,先运算value的值,再判断是否为"king"。如果为king,会执行(nameErrorTip.hide(),"对了,输入为king!")。这个表达式又先将nameErrorTip隐藏,再返回一个"对了,输入为king!"字符串作为 整个return的值。

||、&&、if()逻辑让人头晕

||&&两侧参与运算的是逻辑表达式,if()中也是。但是我们在很多开源代码中看到的||&&参与运算的表达式看起来却好像不是逻辑表达式……

下面节选一段jQuery.tool中的一段源码:

e.circular || (f.onBeforeSeek(function(a, b) {
    setTimeout(function() {
        a.isDefaultPrevented()||(
            n.toggleClass(
                e.disabledClass,
                b <= 0
            ),
            o.toggleClass(
                e.disabledClass,
                b >= f.getSize() - 1
            )
        )
    }, 1)
}),
e.initialIndex || n.addClass(e.disabledClass)),
f.getSize() < 2 && n.add(o).addClass(e.disabledClass),
e.mousewheel && a.fn.mousewheel && b.mousewheel(function(a, b) {
    if (e.mousewheel) {
        f.move(b < 0 ? 1 : -1, e.wheelSpeed || 50);
        return !1
    }
});

这里有多处||&&。但与运算的表达式却是调用某个函数的返回值。

其实,js中的逻辑表达式是按照真值、假值来分的。true是真值;1是真值;一个对象也是真值;false是假值;""0是假值。

在js中&&||不一定都是用来判断一个表达式的逻辑值是truefalse,更多的是用来依据真值或者假值执行相应操作!

我们知道,||运算的时候,会先运算左侧的表达式的值,如果为真值,那么真个表达式就为真值,而同时右侧表达式是真值、假值都不重要,因为右侧表达式都不再继续参与运算了。又如果左侧为假值,则继续运算右侧表达式。

&&则先运算左侧表达式,两侧表达式,一个为假值,则整个表达式为假值。

这里关键是这个真值或者假值的运算过程中,我们可以使用上面介绍的,()将一组表达式串起来执行。也就是说,这个表达式可能会很长很长,我甚至可以定义一个function在里面。这些表达式在执行过程中,有可以进行某些附加操作。比如我们希望这个表达式为真值的时候我们做什么,假值的时候做什么,把这些操作用(),串起来作为一个整体运算。

于是就有了上面的复杂代码。

另外:

if(a){
    b
}

可简写为a&&(b); b可以是一个function调用表达式,或者是多个语句用","串起来。但前提是a已定义,否则会报错。

我们来看个实例吧。是上面例子的升级版。我们加入一个nameInput是否存在的判断:

jQuery(document).ready(function() {
    var nameValidate=function(){
        var value,nameInput=$("#name"),nameErrorTip=$("#nameErrorTip"),msg;
        msg=(value=nameInput.val(),value=="king")?(nameErrorTip.hide(),"对了,输入为king!"):(nameErrorTip.show(),"请输入king!");
        return (nameInput.length&&nameInput.val()&&nameErrorTip.length&&msg)||"没有找到name输入框或者输入框没有值!";
    };
    alert(nameValidate());
});

测试:

//html:<input value="king" id="myName"/>
//结果:弹出“没有找到name输入框或者输入框没有值!”

//<input value="king" id="name"/><div id="nameErrorTip">输入错误!</div>
//结果:弹出“对了,输入为king!”,nameErrorTip被隐藏

return表示中 nameInput.length&&nameInput.val()&&nameErrorTip.length&&msg会先运算 nameInput.length的值,如果length0则表达式为假值,如果为1则为真值。val()操作也是如此,如果val()结果为""则表达式也是假值。几个表达式之间为&&运算,则表示依次运算几个表达式的值,如果都未真值则返回最后一个表达式的值,由于整个表达式与 "没有找到name输入框或者输入框没有值!" 表达式之间是||运算,所以前面的表达式其中一个表达式为假值则返回||右侧的表达式的值,也就是整个“没有找到name输入框或者输入框没有值!”字符串。

说到这里,我之前写过一篇文章专门说到了&&||的真值、假值问题。有兴趣的可以去看看。

谈了这些难以理解的运算符后,大家可能会觉得,这个javascript为什么要搞这些晦涩的运算符呢?

我的理解是因为javascript通常在客户端运行,那么从服务器端将js代码传输到客户端肯定需要耗时。上面的这些运算符都是为了减少代码量。再加上使用压缩工具去掉空格,替换变量名,就可以使用压缩率达到最好。

再这里,我也告诉大家,其实我也非常反对在实际应用中采用这种写法的,因为会对初学者造成阅读障碍。我写这篇文章的目的不是为了让大家以后就这样用,而是告诉大家可以这样用,在一些开源代码中遇到了能看懂。不可为了炫耀而故意写一些晦涩的代码。

最后,为了帮助我们更快的找到变量定义、理清代码整体结构,给大家推荐一个eclipse的js插件:Spket,支持jQuery代码提示哦!

来源:http://www.tashan10.com/

暮成雪 博客

时间: 2024-10-12 22:43:20

(function($){})(jQuery)资料记录的相关文章

jQuery学习记录1

jquery 和 js css里面都是坑呀 this.style.backgroundColor 和 css {background:#8df;} 是冲突的,用了前者,再$(this).addClass("css class name");效果显示不出来. http://youchenglin.iteye.com/blog/685026 前他的一些内容参见下列代码 <!DOCTYPE html> <html> <head> <meta char

文档资料记录

版本控制: git http://git-scm.com/book/zh/ 无线互联网: 一秒钟法则:来自腾讯无线研发的经验分享 图书推荐 国外程序员推荐:每个程序员都应读的书文档资料记录,码迷,mamicode.com

jquery学习记录

i{margin:21px 0}#header-wrapper .Menu-indicator>i,.wrapper-embed .Menu-indicator>i{margin:13px 0}.Menu-popover{background-color:#f7f7f7;display:none;border:1px solid #b5b5b5;position:absolute;z-index:9998}.Menu-popover.is-active{display:block}.Menu_

[Golang][Mac]Go 语言学习资料记录

背景:最近的项目开发语言是GOlang 因此需要做一些简单了解和学习记录 又可以学习一下Google的新语言了,想想有些小激动哦~ 官方网站(需FQ才能打开,比如用蓝灯)https://golang.org/ 1. 下载安装:https://golang.org/ 2. 安装完毕后在Mac打开终端,配置环境变量以及创建目录 1 GOPATH=$HOME 2 echo $GOPATH 3 export PATH=$PATH:$(go env GOPATH)/bin 4 mkdir $HOME/go

JQuery 学习记录

在没有接触jQuery之前,总是听到或看到别人讲原生的JS,感到很奇怪,怎么还有原生的JS,现在才明白原来是相对jQuery来讲的.jQuery是一个很好的框架,运用起来比JS简单很多.在学习他的过程中,也学习了AJAX,可以实现与后台交互,学习时间有点短,对AJAX还不是很熟悉,感觉有点难度. 也已经学习大概一周的时间了,学会了留言板.瀑布流及搜索框的制作.相对来说,前端我掌握的比后端好,不知道是不是自己潜意识排斥,呃,但是总归要学的,不要呆在舒适区,要好好的学习,遇到困难才能有收获. 大体来

jquery 使用记录

1.jquery 筛选一个属性符合多个条件  var myTag=$("input[id=myid][name=myname][type=button]").length; 2.jquery delegate 重复触发事件问题 方法1.阻止事件冒泡  取消span的click事件冒泡,解答:e.stopPropagation()~方法2.判断事件触发者,$('body').delegate('body>div','click',function(){if(e.target!=$(

jquery学习记录四(操作DOM元素)

jQuery 操作DOM元素主要有: 1.使用attr()方法控制元素的属性 2.操作元素的内容 3.操作元素的样式 4.移除属性和样式 5.使用append()方法向元素内追加内容 6.使用appendTo()方法向被选元素内容插入内容 7.使用before()和after()在元素前后插入内容 8.使用clone()方法复制元素 9.替换内容 10.使用wrap()和wrapinner()方法包裹元素和内容 11.使用each()方法遍历元素 12.使用remove()和empty()方法删

一些关于 checkbox的前台 jquery 操作 记录

$(function() { //页面载入函数 var partList = jQuery.parseJSON( '${KeyWordsList}'); $.each(partList,function(key,value){ //console.log(key); // console.log(value['ID']+' '+value['KeyWord']); if(value['ID']%3 == 0){ //<label><input name="Fruit"

jquery学习记录二(过滤性选择器)

过滤性选择器包括: 1.:first过滤选择器 2.:eq(index)过滤选择器 3.:contains(text)过滤选择器 4.:has(selector)过滤选择器 5.:hidden过滤选择器 6.:visible过滤选择器 7.[attribute=value]属性选择器 8.[attribute!=value]属性选择器 9.[attribute*=value]属性选择器 10.:first-child子元素选择器 11.last-child子元素选择器 过滤性选择器,该类型的选择