var name="xiao A";
var obj={
name : "xiao B";
getName : function(){
return function(){
return this.name;
}
}
}
alert(obj.getName()());//返回"xiao A"原因,getName返回的是
//个全局作用域的函数
var name="xiao A";
var obj={
name : "xiao B",
getName : function(){
var o=this;
return function(){
return o.name;
};
}
};
alert(obj.getName()());//返回"xiao B"
//或者直接返回this.name
var name="xiao A";
var obj={
name : "xiao B",
getName : function(){
return this.name;
}
};
alert(obj.getName());//返回"xiao B"
闭包:
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
add();
add();
add();
闭包是可访问上一层函数作用域里变量的函数,即便上一层函数已经关闭。
实例解析
变量 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"