源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

详解JavaScript的闭包、IIFE、apply、函数与对象

  • 时间:2020-09-15 18:01 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:详解JavaScript的闭包、IIFE、apply、函数与对象
[b]目录[/b] [b]一、闭包(Closure)[/b] 1.1、闭包相关的问题 1.2、理解闭包 [b]二、对象[/b] 2.1、对象常量(字面量) 2.2、取值 2.3、枚举(遍历) 2.4、更新与添加 2.5、对象的原型 2.6、删除 2.7、封装 [b]三、函数[/b] 3.1、参数对象 (arguments) 3.2、构造函数 3.3、函数调用 3.3.1、call 3.3.2、apply 3.3.3、caller 3.3.4、Callee 3.5、立即执行函数表达式 (IIFE) 3.5.1、匿名函数与匿名对象 3.5.2、函数与函数表达式 3.5.3、立即执行函数表达式与匿名对象 3.5.4、各种IIFE的写法 3.5.5、参数 3.5.6、添加分号 3.5.7、IIFE的作用 3.5.8、IIFE的变形 [b]四、示例下载[/b] [b]一、闭包(Closure)[/b] [b]1.1、闭包相关的问题[/b] 请在页面中放10个div,每个div中放入字母a-j,当点击每一个div时显示索引号,如第1个div显示0,第10个显示9;方法:找到所有的div,for循环绑定事件。 示例代码:
<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title>闭包</title>
 <style type="text/css">
 div {
 width: 100px;
 height: 100px;
 background: lightgreen;
 float: left;
 margin: 20px;
 font: 30px/100px "microsoft yahei";
 text-align: center;
 }
 </style>
 </head>
 <body>
 <div>a</div>
 <div>b</div>
 <div>c</div>
 <div>d</div>
 <div>e</div>
 <div>f</div>
 <div>g</div>
 <div>h</div>
 <div>i</div>
 <div>j</div>
 <script type="text/javascript">
 var divs=document.getElementsByTagName("div");
 for (var i=0;i<divs.length;i++) {
 divs[i].onclick=function(){
 alert(i);
 }
 }
 </script>
 </body>
</html>
运行结果: [img]http://files.jb51.net/file_images/article/201612/2016122110415819.png[/img] 因为点击事件的函数内部使用外部的变量i一直在变化,当我们指定click事件时并没有保存i的副本,这样做也是为了提高性能,但达不到我们的目的,我们要让他执行的上下文保存i的副本,这种机制就是闭包。 修改后的代码:
<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title>闭包</title>
 <style type="text/css">
 div {
 width: 100px;
 height: 100px;
 background: lightgreen;
 float: left;
 margin: 20px;
 font: 30px/100px "microsoft yahei";
 text-align: center;
 }
 </style>
 </head>
 <body>
 <div>a</div>
 <div>b</div>
 <div>c</div>
 <div>d</div>
 <div>e</div>
 <div>f</div>
 <div>g</div>
 <div>h</div>
 <div>i</div>
 <div>j</div>
 <script type="text/javascript">
 var divs=document.getElementsByTagName("div");
 for (var i=0;i<divs.length;i++) {
 divs[i].onclick=(function(n){
 return function(){
 alert(n); 
 }
 })(i);
 }
 </script>
 </body>
</html>
运行结果: [img]http://files.jb51.net/file_images/article/201612/2016122110415920.png[/img] n是外部函数的值,但是内部函数(点击事件)需要使用,返回函数前的n被临时驻留在内存中给点击事件使用,简单说就是函数的执行上下文被保存起来,i生成了多个副本。 [b]1.2、理解闭包[/b] 闭包概念:当一个内部函数被调用,就会形成闭包,闭包就是能够读取其他函数内部变量的函数,定义在一个函数内部的函,创建一个闭包环境,让返回的这个子程序抓住i,以便在后续执行时可以保持对这个i的引用。内部函数比外部函数有更长的生命周期;函数可以访问它被创建时所处的上下文环境。 Javascript语言特有的"链式作用域"结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量 [b]二、对象[/b] 对象就是“键/值”对的集合并拥有一个连接到原型(prototype)对隐藏连接。 [b]2.1、对象常量(字面量)[/b] 一个对象字面量就是包含在一对花括号中的零个或多个“键/值”对。对象字面量可以出现在任何允许表达式出现的地方。 对象的定义:
//空对象
 var obj1={};
 //对象中的属性
 var obj2={name:"foo",age:19};
 var obj3={"nick name":"dog"};
 //对象中的方法
 var obj4={
 price:99,
 inc:function(){
 this.price+=1;
 }
 }
对象中可包含的内容: 对象常量可以出现在任何允许表达式出现的地方,对象、数组、函数可以相互间嵌套,形式可以多种多样。对象的值可以是:数组,函数,对象,基本数据类型等。
//对象中可包含的内容
 var obj5 = [{
 name: "jack"
 }, {
 name: "lucy", //常量
 hobby:["读书","上网","代码"], //数组
 friend:{name:"mark",height:198,friend:{}}, //对象
 show:function(){ //函数
 console.log("大家好,我是"+this.name);
 }
 }];
 //对象中的this是动态的,指向的是:调用者
 obj5[1].show();
输出:大家好,我是lucy [b]2.2、取值[/b] [b]方法一:直接使用点号运算[/b]
 //3取值
 var obj6={"nick name":"pig",realname:"Rose"};
 console.log(obj6.realname);
 //console.log(obj6.nick name); 错误
[b]方法二:使用索引器,当对象中的key有空格是[/b]
 //3取值
 var obj6={"nick name":"pig",realname:"Rose"};
 console.log(obj6["realname"]);
 console.log(obj6["nick name"]);
[b]2.3、枚举(遍历)[/b] [b]方法一:[/b]
var obj7={weight:"55Kg","nick name":"pig",realname:"Rose"};
 for (var key in obj7) {
 console.log(key+":"+obj7[key]);
 }
运行结果: [img]http://files.jb51.net/file_images/article/201612/2016122110415921.png[/img] 输出顺序是不能保证的。 [b]2.4、更新与添加[/b] 如果对象中存在属性就修改对应值,如果不存在就添加。对象通过引用传递,它们永远不会被复制
var obj8={realname:"King"};
 obj8.realname="Queen"; //修改
 obj8.weight=1000; //添加属性
 obj8.show=function() //添加方法
 {
 console.log(this.realname+","+this.weight);
 }
 obj8.show();
输出: Queen,1000
var obj8={realname:"King"};
 obj8.realname="Queen"; //修改
 obj8.weight=1000; //添加属性
 obj8.show=function() //添加方法
 {
 console.log(this.realname+","+this.weight);
 }
 obj8.show();
 
 //引用
 var obj9=obj8; //obj9指向obj8的引用
 obj9.realname="Jack";
 obj8.show();
输出: [img]http://files.jb51.net/file_images/article/201612/2016122110415922.png[/img] [b]2.5、对象的原型[/b] javascript是一种动态语言,与C#和Java这样的静态语言是不一样的;javascript并没有严格的类型,可以简单认为javascript是由对象组成的,对象间连接到原型(prototype)实现功能的扩展与继承。每个对象都链接到一个原型对象,并且可以从中继承属性,所有通过常量(字面量)创建的对象都连接到Object.prototype,它是JavaScript中的顶级(标配)对象,类似高级语言中的根类。 [img]http://files.jb51.net/file_images/article/201612/2016122110415923.png[/img] 现在我们修改系统中的Object对象,添加一个创建方法,指定要创建对象的原型,实现类似继承功能:
<script type="text/javascript">
 if(typeof Object.beget !== "function")
 {
 Object.create = function(o) {
 //构造函数,用于创建对象
 var F = function() {};
 //指定由构造函数创建的对象的原型
 F.prototype = o;
 //调用构造方法创建新对象
 return new F();
 }
 }
 var rose={
 name:"rose",
 show:function(){
 console.log("姓名:"+this.name);
 }
 };
 rose.show(); //输出
 var lucy=Object.create(rose); //简单认为是:创建一个对象且继承rose
 lucy.name="lucy"; //重写
 lucy.show();
 </script>
运行结果: [img]http://files.jb51.net/file_images/article/201612/2016122110415924.png[/img] 原型关系是一种动态关系,如果修改原型,该原型创建的对象会受到影响。
var lucy=Object.create(rose); //简单认为是:创建一个对象且继承rose
 lucy.name="lucy"; //重写
 
 var jack=Object.create(rose);
 jack.name="jack";
 
 //修改原型中的方法
 rose.show=function(){
 console.log("姓名->"+this.name);
 }
 
 lucy.show();
 jack.show();
结果: [img]http://files.jb51.net/file_images/article/201612/2016122110415925.png[/img] 关于原型在函数中会再讲到。 [b]2.6、删除[/b]
 //删除属性
 delete mark.name; 
 //调用方法,输出:姓名:undefined
 mark.show(); 
 //删除函数
 delete mark.show; 
 //错误,mark.show is not a function
 mark.show();
删除不用的属性是一个好习惯,在某些情况下可能引发内存泄漏。 [b]2.7、封装[/b] 使用对象封装的好处是可以减少全局变量的污染机会,将属性,函数都隶属一个对象。 [b]封装前:[/b]
var name="foo"; //name是全局的,被暴露
 i=1; //全局的,没有var关键字声明的变量是全局的,与位置关系不大
 function show(){ //show 是全局的,被暴露
 console.log("name->"+name);
 console.log(++i);
 }
 //i是全局的 2
 show(); 
 //3
 show();
[img]http://files.jb51.net/file_images/article/201612/2016122110415926.png[/img] [b]封装后:[/b]
//对外只暴露bar,使用闭包封装
 var bar=function(){
 var i=1;
 return{
 name:"bar",
 show:function(){
 console.log("name->"+this.name);
 console.log(++i);
 }
 };
 }; 
 var bar1=bar();
 //2
 bar1.show();
 //3
 bar1.show(); 
 var bar2=bar();
 //2,因为被封装,且闭包,i是局部私有的
 bar2.show();
运行结果: [img]http://files.jb51.net/file_images/article/201612/2016122110415927.png[/img] [b]三、函数[/b] javascript中的函数就是对象,对象就是“键/值”对的集合并拥有一个连接到原型对隐藏连接。 [img]http://files.jb51.net/file_images/article/201612/2016122110415928.png[/img] [b]3.1、参数对象 (arguments)[/b] 第一个函数中有一个默认对象叫arguments,类似数组,但不是数组,该对象是传递给函数的参数。
<script type="text/javascript">
 function counter(){
 var sum=0;
 for(var i=0;i<arguments.length;i++){
 sum+=arguments[i];
 }
 return sum;
 }
 console.log(counter(199,991,1,2,3,4,5));
 console.log(counter());
 </script>
运行结果: 1205 0 这里的arguments是一个隐式对象,不声明也在函数中,内部函数可以访问外部函数的任意内容,但是不能直接访问外部函数的arguments与this对象。
function f1()
 {
 console.log(arguments.length);
 f2=function()
 {
 console.log(arguments.length);
 }
 return f2;
 }
 var f=f1(1,2,3);
 f();
运行结果: 3 0 [b]3.2、构造函数[/b] 在javascript中对象构造函数可以创建一个对象。
<script type="text/javascript">
 /*构造函数*/
 //可以简单的认为是一个类型的定义
 function Student(name,age){
 this.name=name;
 this.age=age;
 this.show=function(){
 console.log(this.name+","+this.age);
 }
 }
 //通过new关键字调用构造函数,创建一个对象tom
 var rose=new Student("rose",18);
 var jack=new Student("jack",20);
 
 rose.show();
 jack.show();
 </script>
[img]http://files.jb51.net/file_images/article/201612/2016122110415929.png[/img] [b]3.3、函数调用[/b] [b]3.3.1、call[/b] 调用一个对象的一个方法,以另一个对象替换当前对象 [code]call([thisObj[,args])[/code] hisObj 可选项。将被用作当前对象的对象。args 将被传递方法参数序列。 call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。 示例:
/*构造函数*/
 function Student(name,age){
 this.name=name;
 this.age=age;
 }
 show=function(add){
 console.log(add+":"+this.name+","+this.age);
 }
 //通过new关键字调用构造函数,创建一个对象tom
 var rose=new Student("rose",18);
 var jack=new Student("jack",20);
 //调用show方法,指定上下文,指定调用对象,this指向rose,“大家好是参数”
 show.call(rose,"大家好");
 show.call(jack,"Hello");
运行结果: [img]http://files.jb51.net/file_images/article/201612/2016122110415930.png[/img] call方法中的参数都可以省去,第1个参数表示在哪个对象上调用该方法,或this指向谁,如果不指定则会指向window对象。 示例:
 var name="无名";
 var age=18;
 show.call();
结果: undefined:无名,18 [b]3.3.2、apply[/b] [code]apply([thisObj[,argArray]])[/code] 应用某一对象的一个方法,用另一个对象替换当前对象,与call类似。 如果 argArray 不是一个有效的数组或者不是arguments对象,那么将导致一个 TypeError。 如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。 对于第一个参数意义都一样,但对第二个参数: apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。 如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3]) 同时使用apply的好处是可以直接将当前函数的arguments对象作为apply的第二个参数传入 示例代码:
/*构造函数*/
 function Student(name,age){
 this.name=name;
 this.age=age;
 }
 show=function(greeting,height){
 console.log(greeting+":"+this.name+","+this.age+","+height);
 }
 //通过new关键字调用构造函数,创建一个对象tom
 var rose=new Student("rose",18);
 var jack=new Student("jack",20);
 //调用show方法,指定上下文,指定调用对象,this指向rose,“大家好是参数”
 show.apply(rose,["大家好","178cm"]);
 show.apply(jack,["Hello","188cm"]);
运行结果: [img]http://files.jb51.net/file_images/article/201612/2016122110415931.png[/img] 从上面的示例中可以发现apply的第2个参数是一个数组,数组中的内容将映射到被调用方法的参数中,如果单这样看发现不如call方便,其实如果直接取方法的参数arguments则apply要方便一些。通过简单的变化就可以替代call。
 function display(){
 show.apply(jack,arguments);
 }
 display("hi","224cm");
结果: [code]hi:jack,20,224cm[/code] javascript里call和apply操作符可以随意改变this指向 如果在javascript语言里没有通过new(包括对象字面量定义)、call和apply改变函数的this指针,函数的this指针都是指向window的。 关于this指针,我的总结是:是谁调用的函数,那么这个函数中的this指针就是它;如果没有明确看出是谁调用的,那么应该就是window调用的,那么this指针就是window。 [b]3.3.3、caller[/b] 在一个函数调用另一个函数时,被调用函数会自动生成一个caller属性,指向调用它的函数对象。如果该函数当前未被调用,或并非被其他函数调用,则caller为null。 在JavaScript的早期版本中,Function对象的caller属性是对调用当前函数的函数的引用
function add()
 {
 console.log("add被调用");
 //add方法的调用函数,如果调用add方法的不是函数则为null
 console.log(add.caller);
 }
 function calc(){
 add();
 }
 //直接调用add方法
 add(); 
 //间接通过calc方法调用
 calc();
运行结果: [img]http://files.jb51.net/file_images/article/201612/2016122110415932.png[/img] caller与this还是有区别的,this是指调用方法的对象,而caller是指调用函数的函数。
<script type="text/javascript">
 function add(n)
 {
 console.log("add被调用");
 if(n<=2){
 return 1;
 }
 return add.caller(n-1)+add.caller(n-2);
 }
 function calc(n){
 console.log("calc被调用");
 return add(n);
 }
 //1 1 2
 console.log(calc(3));
 </script>
结果: [img]http://files.jb51.net/file_images/article/201612/2016122110415933.png[/img] [b]3.3.4、Callee[/b] 当函数被调用时,它的arguments.callee对象就会指向自身,也就是一个对自己的引用
function add(n1,n2){
 console.log(n1+n2);
 //arguments.callee(n1,n2); //指向add方法
 return arguments.callee;
 }
 add(1,2)(3,4)(5,6)(7,8)(8,9);
运行结果: [img]http://files.jb51.net/file_images/article/201612/2016122110415934.png[/img] 当第1次调用add方法时输入3,立即将函数返回再次调用,每次调用后又返回自己,这样可以实现链式编程。 [b]3.5、立即执行函数表达式 (IIFE)[/b] IIFE即Immediately-Invoked Function Expression,立即执行函数表达式 [b]3.5.1、匿名函数与匿名对象[/b] 匿名函数就是没有名称的函数,javascript中经常会使用匿名函数实现事件绑定,回调,实现函数级的私有作用域,如下所示:
 function(){
 console.log("这是一个匿名函数");
 };
匿名对象:
 {
 name:"foo",
 show:function(){
 console.log(this.name);
 }
 }
没有名称的匿名函数也叫函数表达式,它们间是有区别的。 [b]3.5.2、函数与函数表达式[/b] 下面是关于函数与函数表达式定义时的区别 a)、函数定义(Function Declaration) [code]function Identifier ( Parameters ){ FunctionBody }[/code] function 函数名称(参数){函数主体} 在函数定义中,参数(Parameters)标识符(Identifier )是必不可少的。如果遗漏,会报提示错误: 代码:
 function(){
 console.log("这是一个匿名函数");
 };
结果: [img]http://files.jb51.net/file_images/article/201612/2016122110415935.png[/img] b)、函数表达式(Function Expression) [code]function Identifier(Parameters){ FunctionBody }[/code] 函数表达式中,参数和标识符都是可选的,与函数定义的区别是标识符可省去。 其实,"function Identifier(Parameters){ FunctionBody }"并不是一个完整的函数表达式,完整的函数的表达式,需要一个赋值操作。 比如: [code]var name=function Identifier(Parameters){ FunctionBody }[/code] [b]3.5.3、立即执行函数表达式与匿名对象[/b]
 //1 正常定义函数
 function f1(){
 console.log("正常定义f1函数");
 };
 //2 被误解的函数表达式
 function(){
 console.log("报错Unexpected token (");
 }();
 //3 IIFE,括号中的内容被解释成函数表达式
 (function(){
 console.log("IIFE,正常执行");
 })();
 //4 函数表达式
 var f2=function(){
 console.log("这也被视为函数表达式");
 };
第3种写法为什么这样就能立即执行并且不报错呢?因为在javascript里,括号内部不能包含语句,当解析器对代码进行解释的时候,先碰到了(),然后碰到function关键字就会自动将()里面的代码识别为函数表达式而不是函数声明。 如果需要将函数表达式或匿名对象立即执行,可以使用如下方法:
<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title>IIFE</title>
 </head>
 <body>
 <script type="text/javascript">
 //调用匿名函数
 (function() {
 console.log("这是一个函数表达式");
 })();
 //调用匿名对象
 ({
 name: "foo",
 show: function() {
 console.log(this.name);
 }
 }).show();
 console.log({
 a: 1
 }.a);
 console.log({
 a: function() {}
 }.a());
 </script>
 </body>
</html>
运行结果: [img]http://files.jb51.net/file_images/article/201612/2016122110415936.png[/img] [b]3.5.4、各种IIFE的写法[/b]
//最常用的两种写法
(function(){ /* code */ }()); // 老师推荐写法
(function(){ /* code */ })(); // 当然这种也可以
// 括号和JS的一些操作符(如 = && || ,等)可以在函数表达式和函数声明上消除歧义
// 如下代码中,解析器已经知道一个是表达式了,于是也会把另一个默认为表达式
// 但是两者交换则会报错
var i = function(){ return 10; }();
true && function(){ /* code */ }();
0, function(){ /* code */ }();
// 如果你不怕代码晦涩难读,也可以选择一元运算符
!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();
// 你也可以这样
new function(){ /* code */ }
new function(){ /* code */ }() // 带参
如果是函数表达式,可直接在其后加"()"立即执行。 如果是函数声明,可以通过"()"、"+"、"-"、"void"、"new"等运算符将其转换为函数表达式,然后再加"()"立即执行。 [img]http://files.jb51.net/file_images/article/201612/2016122110415937.png[/img] [b]3.5.5、参数[/b] 函数表达式也是函数的一种表达形式,同样可以像函数一样使用参数,如下所示:
 (function (n){
 console.log(n);
 })(100);
输出:100 其实通过IIFE还能形成一个类似的块级作用域,当块内的程序在使用外部对象时将优先查找块内的对象,再查找块外的对象,依次向上。
 (function(win,undfd){
 win.console.log("Hello"==undfd);
 })(window,undefined);
[b]3.5.6、添加分号[/b] 为了避免与其它的javascript代码产生影响后报错,常常会在IIFE前增加一个分号,表示前面所有的语句都结束了,开始新的一语句。
 var k=100
 (function (n){
 console.log(n);
 })(k);
上面的脚本会报错,因为javascript解释器会认为100是函数名。
 var k=100
 ;(function (n){
 console.log(n);
 })(k);
这样就正确了,在javascript中一行语句的结束可以使用分号,也可以不使用分号,因为一般的自定义插件会使用IIFE,这是一段独立的代码,在应用过程中不能保证用户会加上分号,所以建议在IIFE前加上分号。 [b]3.5.7、IIFE的作用[/b] [b]1)、提高性能[/b] 减少作用域查找时间。使用IIFE的一个微小的性能优势是通过匿名函数的参数传递常用全局对象window、document、jQuery,在作用域内引用这些全局对象。JavaScript解释器首先在作用域内查找属性,然后一直沿着链向上查找,直到全局范围。将全局对象放在IIFE作用域内提升js解释器的查找速度和性能。 function(window, document, $) { }(window, document, window.jQuery); [b]2)、压缩空间[/b] 通过参数传递全局对象,压缩时可以将这些全局对象匿名为一个更加精简的变量名
function(w, d, $) { 
}(window, document, window.jQuery);
[b]3)、避免冲突[/b]  匿名函数内部可以形成一个块级的私有作用域。 [b]4)、依赖加载[/b] 可以灵活的加载第三方插件,当然使用模块化加载更好(AMD,CMD),示例如下。 A.html与B.html文件同时引用公用的common.js文件,但是只有A.html需要使用到StuObj对象,B.html不需要,但使用其它方法。 Student.js
var StuObj = {
 getStu: function(name) {
 return new Student(name);
 }
}
/*构造函数*/
function Student(name) {
 this.name = name;
 this.show = function() {
 console.log("Hello," + this.name);
 }
}
Common.js
function other1() {}
function other2() {}
(function($) {
 if($) {
 $.getStu("Tom").show();
 }
})(typeof StuObj=="undefined"?false:StuObj);
A.HTML
<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title>A</title>
 </head>
 <body>
 <script src="js/Student.js" type="text/javascript" charset="utf-8"></script>
 <script src="js/common.js" type="text/javascript" charset="utf-8"></script>
 </body>
</html>
B.HTML
<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title></title>
 </head>
 <body>
 <script src="js/common.js" type="text/javascript" charset="utf-8"></script>
 <script type="text/javascript">
 other1();
 </script>
 </body>
</html>
[b]3.5.8、IIFE的变形[/b] 也许有人会说IIFE将参数放在最后,需要移动到文档的末尾才能看到参数,比较麻烦,那么可以将IIFE变形为如下形式:
(function(n){
 console.log(n);
 
 
 
 
 
 
 
 //认为这里有30000代码
 
 
 
 
 
 
 
 }(100));
如果中间有很长的代码,参数100只有到文档的末尾才可以看得到,变形后的结果:
(function(exp){
 exp(100);
 }(function(n){
 console.log(n);
 //认为这里有30000代码
 }));
修改后的代码中有两个函数表达式,一个作为参数,就是我们主要要完成的功能向控制台输出数字,另一个作来IIFE立即执行的函数,主要的功能函数变成的IIFE的参数了。
(function(win, doc, $) {
 }(window, document, jQuery));
 (
 function(library) {
 library(window, document, window.jQuery);
 }
 (function(window, document, $) {
 })
 );
bootstrap的写法:
+function(yourcode) {
 yourcode(window.jQuery, window, document);
 }(function($, window, document) {
 $(function() {}); //jQueryDOM加载完成事件
 });
结合call或apply的写法:
 (function(x){console.log(x)}).call(window,888);
 (function(x){console.log(x)}).apply(window,[999]);
输出:888 999 [b]四、示例下载[/b] [url=http://xiazai.jb51.net/201612/yuanma/javascript003-master_jb51.rar]http://xiazai.jb51.net/201612/yuanma/javascript003-master_jb51.rar[/url] 以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持编程素材网!
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部