首页 > 代码库 > 锋利的Jquery解惑系列(一)------基本概念大锅炖
锋利的Jquery解惑系列(一)------基本概念大锅炖
声明:虽然是基本概念但也是笔者经过一番学习才总结的这些文章,所以他不包括Jquery优缺点、特点、语法的介绍。
概念一:jQuery对像与DOM对象
DOM(Document Object Model, 文档对象模型)他可以表示成数据结构的树
<html> <head></head> <body> <h1></h </body></html>
就像上面表示html、head、body、h1都是DOM元素节点并且具有父、兄关系,可以通过JS中的方法获得这些方法
var domOjb = document.getElementBy("id");
jQuery对象就是通过jQuery包装DOM对象后产生的对象
jQuery对象是jQuery独有的,如果一个对象是jQuery对象,那么就可以使用jQuery里的方法
$("#foo").html()//获得id=foo的元素内的HTML代杩
等价于:
document.getElementById("foo").innerHTML;
两者获取的对象是不同的,所以他们的方法也不能相互调用
jQuery对象与DOM对象的相互转换
var #cr = $("#cr");var ce = $cr[0];
或
var $cr = $("#cr");var cr = $cr.get(0);
var cr = document.getElementById("cr");var $cr = $(cr);
概念二:闭包在插件中的应用
关于闭包这个概念是困惑我最久的东西,$、jQuery、()、{}这些字符串的一开始的写法是让人很是费解,希望这次我能够说青楚,也能大家少走弯路。
闭包在插件开发过程是用的最多的,说白了他就有点类似java里面的内类。
在这里可以先补上JS闭包的概念:http://www.cnblogs.com/mzwr1982/archive/2012/05/20/2509295.html
在理解闭包以前.最好能先理解一下作用域链的含义,简单来说,作用域链就是函数在定义的时候创建的,用于寻找使用到的变量的值的一个索引,而他内 部的规则是,把函数自身的本地变量放在最前面,把自身的父级函数中的变量放在其次,把再高一级函数中的变量放在更后面,以此类推直至全局对象为止.当函数 中需要查询一个变量的值的时候,js解释器会去作用域链去查找,从最前面的本地变量中先找,如果没有找到对应的变量,则到下一级的链上找,一旦找到了变 量,则不再继续.如果找到最后也没找到需要的变量,则解释器返回undefined.
了解了作用域链,我们再来看看js的内存回收机制,一般来说,一个函数在执行开始的时候,会给其中定义的变量划分内存空间保存,以备后面的语句 所用,等到函数执行完毕返回了,这些变量就被认为是无用的了.对应的内存空间也就被回收了.下次再执行此函数的时候,所有的变量又回到最初的状态,重新赋 值使用.但是如果这个函数内部又嵌套了另一个函数,而这个函数是有可能在外部被调用到的.并且这个内部函数又使用了外部函数的某些变量的话.这种内存回收 机制就会出现问题.如果在外部函数返回后,又直接调用了内部函数,那么内部函数就无法读取到他所需要的外部函数中变量的值了.所以js解释器在遇到函数定 义的时候,会自动把函数和他可能使用的变量(包括本地变量和父级和祖先级函数的变量(自由变量))一起保存起来.也就是构建一个闭包,这些变量将不会被内 存回收器所回收,只有当内部的函数不可能被调用以后(例如被删除了,或者没有了指针),才会销毁这个闭包,而没有任何一个闭包引用的变量才会被下一次内存 回收启动时所回收.
也就是说,有了闭包,嵌套的函数结构才可以运作,这也是符合我们的预期的.然后,闭包还有一些特性,却往往让程序员觉得很难理解.
看看下面一段代码.
var result=[];function foo(){ var i= 0; for (;i<3;i=i+1){ result[i]=function(){ alert(i) } }};foo();result[0](); // 3result[1](); // 3result[2](); // 3
这段代码中,程序员希望foo函数中的变量i被内部循环的函数使用,并且能分别获得他们的索引,而实际上,只能获得该变量最后保留的值,也就是说.闭包中所记录的自由变量,只是对这个变量的一个引用,而非变量的值,当这个变量被改变了,闭包里获取到的变量值,也会被改变.
解决的方法之一,是让内部函数在循环创建的时候立即执行,并且捕捉当前的索引值,然后记录在自己的一个本地变量里.然后利用返回函数的方法,重写内部函数,让下一次调用的时候,返回本地变量的值,改进后的代码:
var result=[];function foo(){ var i= 0; for (;i<3;i=i+1){ result[i]=(function(j){ return function(){ alert(j); }; })(i); }};foo();result[0](); // 0result[1](); // 1result[2](); // 2
保护 i变量的访问,并且一直保存i在内存中,可以一直增加-------这是闭包的主要作法
function a(){ var i=0; function b(){ alert(++i); } return b;}var c = a();c(); //1c(); //2
内部函数可以访问它们所在的外部函数中专声明的所有局部变量、参数和声明的其它内部函数,当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包
利用内部函数定义的临时变量不会影响全局空间,于是就有下面这种写法:
(function(){})();定义了一个匿名函数function(){}然后用()括起来,接着用()来执行这个函数这就是典型的()()写法
如果要传参数可以是:
(function($){ $("div p").click("这里用$可不会和其它插件冲突哦"); })(jQuery);相当于:function temp($){ $("div p").click("这里用$可不会和其它插件冲突哦"); } temp(jQuery)此时传入jQuery对角作为实际参数 因为我们实际传入的参数是jQuery,所以形参$就是作为jQuery对象的缩写
来看一段jQuery代码:
((function($){ var foo; var bar = function(){ /*在匿名函数内部的函数都可以访问foo,即使是在匿名函数的外部调用bar()的时候, 也可以在 bar()的内部访问到foo,但是匿名函数的外部直接访问foo是做不到的*/ } /*下面的语名让匿名函数内部的函数bar()逃逸到全局可访问的范围内 这样就可以在匿名函数的外部通过调用jQuery.BAR()来访问内部定 义的函数bar(),并且内部函数bar()也能访问匿名函数内的变量foo*/ $.BAR = bar;})(jQuery)
锋利的Jquery解惑系列(一)------基本概念大锅炖