实例解析 变量 add 指定了函数自我调用的返回字值。 自我调用函数只执行一次。设置计数器为 0。并返回函数表达式。 add变量可以作为一个函数使用。非常棒的部分是它可以访问函数上一层作用域的计数器。 这个叫作 JavaScript 闭包。它使得函数拥有私有变量变成可能。 计数器受匿名函数的作用域保护,只能通过 add 方法修改。
// 高级程序语言java等 有for if块级作用域(与函数作用域区别)而js没有 function test(){ for(var i = 1;i < 5; i++){ alert(i); } alert(i);//依然输出6,没有块级作用域,且函数结束后i才会被回收 } alert(i);//undefined 可以将for循环单独定义在一个作用域执行 (function ( ){ alter("直接执行");})( );垃圾收集器的两种方法:
引用计数法标记方法(被使用,没有被使用)面向对象 建立对象的方式: 1. 工厂模式 function createPerson( name , age ){ var obj=new Object(); obj.name = name; obj.age = age ; obj.sayName = function(){}; return obj; } 2. 构造函数式 new Date Array(推荐) function Person(name, age){ this.name = name ; this.age = age ; this.sayName = function(){}; } 创建对象的方式
当做构造函数使用 var p1=new Person(“小明”,20,”男”);作为普通函数调用 Person(“小明”,20,”男”);//Person本身就是函数,在全局环境里定义并赋值,直接定义在window上,this指的是window 3.在另一个对象中调用 var obj=new Object(); //call apply 把方法绑定到当前对象上 Person.call(obj,”小明”,18); important原型对象: 构造函数设置为Person否则为Object并且需要设置为不可枚举
important
/../js/CommonUtil.js /** *@author Grey */ /** *BH 命名空间 namespace */ var BH = {}; /** *借口需要两个参数 * 参数1:接口的名字(string) * 参数2:接收方法名称的集合(数组)(array) * */ BH.Interface = function(name,methods){ //判断接口的参数 if(arguments.length != 2){ throw new Error('this interface constructor arguments must be 2 length!'); } this.name = name ; this.methods = [] ; for(var i = 0,len = methods.length ; i < len ; i++){ if( typeof methods[i] !== 'string'){ throw new Error('the Interface method name is error!'); } this.methods.push(methods[i]); } }; //检验接口 BH.Interface.ensureImplements = function(object){ if(arguments.length < 2){ throw new Error('Interface.ensureImplements method constructor arguments must be >=2!'); } for(var i = 1 , len = arguments.length ; i < len ; i++){ var instanceInterface = arguments[i]; if(instanceInterface.constructor !== BH.Interface){ throw new Error('the arguments constructor not be Interface Class'); } for(var j = 0 ; j < instanceInterface.methods.length ; j++){ var methodName = instanceInterface.methods[j]; if(!object[methodName] || typeof object[methodName] !== 'function'){ throw new Error('the method name'+ methodName + 'is not found !'); } } } }; BH.extend = function(sub , sup){ //目的:实现只继承父类的原型对象 var F = new Function();//1.创建一个空函数 用来中转 F.prototype = sup.prototype;//2.实现空函数的原型对象和超类的原型对象转换 sub.prototype = new F();//3.原型继承 sub.prototype.constructor = sub ;//4.还原子类构造器 sub.supClass = sup.prototype ; //自定义一个子类的静态属性 接受父类的原型对象 //判断父类原型对象的构造器(加保险) if(sup.prototype.constructor == Object.prototype.constructor){ sup.prototype.constructor == sup ;//手动还原父类原型对象构造器 } }; //遍历数组实现 Array.prototype.each = function(fn){ try{ this.i ||(this.i = 0); if(this.length >0 && fn.constructor == Function){ while(this.i < this.length){ var e = this[this.i]; if(e && e.constructor == Array){ e.each(fn); }else{ fn.call(e,e); } this.i++; } this.i = null;//释放内存 垃圾回收机制回收变量 } }catch(ex){ } return this; }; <script type="text/javascript" charset="UTF-8" src='../js/CommonUtil.js'></script> <script type="text/javascript" charset="UTF-8"> //目的就是生产一台车 //单体模式 var CarFactory = { createCar : function(type){ var car; switch(type){ case 'Benz': car = new Benz();break; case 'Audi': car = new Audi();break; case 'Bwm' : car = new Bwm();break; default: 'not buy it!'; } //检验接口实现 BH.Interface.ensureImplements(car,CarInterface); return car; } }; function CarShop(){}; CarShop.prototype = { constructor : CarShop , sellCar : function(type){ var car = CarFactory.createCar(type); /*var car; switch(type){ case 'Benz': car = new Benz();break; case 'Audi': car = new Audi();break; case 'Bwm' : car = new Bwm();break; default: 'not buy it!'; } //检验接口实现 BH.Interface.ensureImplements(car,CarInterface);*/ return car; } }; //定义接口 var CarInterface = new BH.Interface('CarInterface',['start','run']); function BaseCar(){}; BaseCar.prototype = { constructor : BaseCar, start : function(){alert(this.constructor.name+'..start');}, run : function(){ alert(this.constructor.name+'..run ');} }; function Benz(){}; BH.extend(Benz,BaseCar);//鸭式继承 // Benz.prototype.start = function(){alert('Benz...start!');}; // Benz.prototype.run = function(){alert('Benz...run');}; function Audi(){}; BH.extend(Audi,BaseCar);//必须在添加函数前 Audi.prototype.driveCar = function(){alert('drive..Audi');}; function Bmw(){}; BH.extend(Bmw,BaseCar); var shop = new CarShop(); var car = shop.sellCar('Audi'); car.start(); car.driveCar(); </script>
细粒度和粗粒度
<script type="text/javascript" charset="UTF-8"> //目的就是生产一台车 //单体模式 var CarFactory = { createCar : function(type){ //利用eval动态创建实例对象 var car = eval('new '+type+'()'); //检验接口实现 BH.Interface.ensureImplements(car,CarInterface); return car; } }; function CarShop(){}; CarShop.prototype = { constructor : CarShop , sellCar : function(type){ this.abstractSellCar(type); }, abstractSellCar : function(){ throw new Error('this method is abstract..'); } }; function BenzCarShop(){}; BH.extend(BenzCarShop,CarShop); BenzCarShop.prototype = { constructor : CarShop, sellCar : function(type){ var car; var types = ['Benz']; for(t in types){ if(types[t]=== type){ car = CarFactory.createCar(type); return car; }else{ alert("没有你要的型号"); } } } }; function AudiCarShop(){}; BH.extend(AudiCarShop,CarShop); AudiCarShop.prototype = { constructor : CarShop, sellCar : function(type){ var car; var types = ['Audi']; for(t in types){ if(types[t]=== type){ car = CarFactory.createCar(type); return car; }else{ alert("没有你要的型号"); } } } }; //定义接口 var CarInterface = new BH.Interface('CarInterface',['start','run']); function BaseCar(){}; BaseCar.prototype = { constructor : BaseCar, start : function(){alert(this.constructor.name+'..start');}, run : function(){ alert(this.constructor.name+'..run ');} }; function Benz(){}; BH.extend(Benz,BaseCar);//鸭式继承 // Benz.prototype.start = function(){alert('Benz...start!');}; // Benz.prototype.run = function(){alert('Benz...run');}; function Audi(){}; BH.extend(Audi,BaseCar);//必须在添加函数前 Audi.prototype.driveCar = function(){alert('drive..Audi');}; function Bmw(){}; BH.extend(Bmw,BaseCar); var shop = new AudiCarShop(); var car = shop.sellCar('Audi'); car.start(); car.driveCar(); </script>//组合模式
<script type="text/javascript" charset="UTF-8" src='../js/CommonUtil.js'></script> <script type="text/javascript" charset="UTF-8"> var CompositeInterface = new BH.Interface('CompositeInterface',['getChild','addChild']); var LeafInterface = new BH.Interface('LeafInterface',['hardworking','sleeping']); var Composite = function(name){ this.name = name ; this.type = 'Composite';//说明对象类型(组合对象) this.childrens = []; }; Composite.prototype = { constructor : Composite, addChild : function(child){ this.childrens.push(child); return this; }, getChild : function(name){ var pushleaf = function(item){ if(item.type == 'Composite'){ item.childrens.each(arguments.callee); }else if(item.type == 'Leaf'){ elements.push(item); } }; var elements= []; if(name &&this.name !== name){ this.childrens.each(function(item){ if(item.name == name && item.type == 'Composite'){ this.childrens.each(pushleaf); }else if(item.name != name &&item.type == 'Composite'){ this.childrens.each(arguments.callee); }else if(item.name == name && item.type == 'Leaf'){ elements.push(item); } }); }else{ this.childrens.each(pushleaf); } return elements; }, hardworking : function(name){ var leafObjects = this.getChild(name); for(var i = 0; i < leafObjects.length ; i ++){ leafObjects[i].hardworking(); } }, sleeping : function(){ } }; var Leaf = function(name){ this.name = name ; this.type = 'Leaf'; }; Leaf.prototype = { constructor : Leaf, addChild : function(child){ throw new Error('this method is disabled...'); }, getChild : function(name){ if(this.name == name){ return this; } return null; }, hardworking : function(){ document.write(this.name + '...努力工作'); }, sleeping : function(){ document.write(this.name + '...睡觉'); } }; //测试数据 var p1 = new Leaf('张1'); var p2 = new Leaf('张2'); var p3 = new Leaf('张3'); var p4 = new Leaf('张4'); var p5 = new Leaf('张5'); var p6 = new Leaf('张6'); var p7 = new Leaf('张7'); var p8 = new Leaf('张8'); var p9 = new Leaf('张9'); var p10 = new Leaf('张10'); var p11 = new Leaf('张11'); var p12 = new Leaf('张12'); //四层节点 var dept1 = new Composite('长沙开发部门'); dept1.addChild(p1).addChild(p2).addChild(p3); var dept2 = new Composite('北京销售部门'); dept2.addChild(p4).addChild(p5).addChild(p6); var dept3 = new Composite('长沙开发部门'); dept3.addChild(p7).addChild(p8).addChild(p9); var dept4 = new Composite('北京开发部门'); dept4.addChild(p10).addChild(p11).addChild(p12); var org1 = new Composite('北京分公司'); org1.addChild(dept1).addChild(dept2); var org2 = new Composite('长沙分公司'); org2.addChild(dept3).addChild(dept4); var org = new Composite("总部"); org.addChild(org1).addChild(org2); org.hardworking("北京开发部门"); </script>jQuery •对于HTML元素本身就带有的固有属性,在处理时,使用prop方法。 •对于HTML元素我们自己自定义的DOM属性,在处理时,使用attr方法。 attr包含prop,prop只能处理固有属性,attr都可以 上面的描述也许有点模糊,举几个例子就知道了。
<a href="http://www.baidu.com" target="_self" class="btn">百度</a> 这个例子里元素的DOM属性有“href、target和class”,这些属性就是元素本身就带有的属性,也是W3C标准里就包含有这几个属性,或者说在IDE里能够智能提示出的属性,这些就叫做固有属性。处理这些属性时,建议使用prop方法。
`<a href="#" id="link1" action="delete">删除</a> 这个例子里元素的DOM属性有“href、id和action”,很明显,前两个是固有属性,而后面一个“action”属性是我们自己自定义上去的,元素本身是没有这个属性的。这种就是自定义的DOM属性。处理这些属性时,建议使用attr方法。使用prop方法取值和设置属性值时,都会返回undefined值。
再举一个例子: <input id="chk1" type="checkbox" />是否可见 <input id="chk2" type="checkbox" checked="checked" />是否可见 像checkbox,radio和select这样的元素,选中属性对应“checked”和“selected”,这些也属于固有属性,因此需要使用prop方法去操作才能获得正确的结果。 $("#chk1").prop("checked") == false $("#chk2").prop("checked") == true 如果上面使用attr方法,则会出现: $("#chk1").attr("checked") == undefined $("#chk2").attr("checked") == "checked"