浅谈 js中的几种模式 (一)
2016-01-03 22:47
696 查看
今天看了《JavaScript高级程序设计》(第三版)这本书,颇有收获,总想写点什么,只恨自己菜鸟一只写不出什么真知灼见,只能。。。。。。好了废话不多说,开篇了。
大家都知道在js中可以用Object构造函数和对象字面量这两种方式创建对象
但是上诉两种创建对象的方法都有一个明显的缺点那就是使用同一个接口创建很多对象会产生很多重复的代码。为了解决这个问题js引入了工厂模式:
varperson1=createPerson("DJL1",22,"student1");
varperson2=createPerson("DJL2",22,"student2");
alert(typeofcreatePerson("DJL2",22,"student2"));//object
这样我们在利用createPerson这个函数接口创建很多对象时,就不用每个都要去写o.name=name;o.age=age;这些重复的代码。工厂模式创建对象就在于在这个函数接口内部利用Object构造函数又创建了一个新的对象,然后return出来。但是,但是,但是,这种模式也是有问题的-----你怎么用instanceof,即你怎么知道某个对象的具体类型,这样吗
为了解决这个问题,构造函数模式出来了
与工厂模式不同的是:1没有显示的创建新对象2直接将属性和方法赋值给了this对象3没有return语句4函数名首字母大写
要创建CreatePerson的实例必须要使用关键字new。以这种方式新建对象会经历如下有如下4个过程
1创建新的对象
2将构造函数的作用域赋给新对象(因此this就指向了新对象)
3执行构造函数中的代码
4返回新对象
利用构造函数模式,我们可以将来将他的实例标识为一种特定的类型。然而这种模式也是有缺点的,上例中我们创建了person1和person2这两个实例,有相同的方法名sayName,但是这两个同名函数却不是相等的
但是有时我们同一个构造函数不同实例中的同名函数来共同完成一件事情怎么办,下面这是一种办法
我们把sayName函数的定义转移到了构造函数外部,而在构造函数内部我们把sayName设置成了全局变量。这样person1和person2就共享了在全局域中定义的sayName()函数。这样做确实解决了共享性问题,但是如果有很多个这样的函数呢,那边要定义多个全局函数,那么封装性就不言而喻了。为了解决这个问题,原型模式就脱颖而出了。
我们创建的每一个函数都有一个prototype属性,该属性是一个指针,指向一个对象。这个对象包含了所有实例共享的属性和方法。使用原型对象的好处就是可以让所有对象实例共享它所包含的属性和方法。我们不必在构造函数中去定义对象实例的信息,而是可以将这些信息添加到原型对象中。
此时我们仍然可以通过CreatePerson这个构造函数来创建实例,并且能够访问sayName这个函数,与构造函数模式的区别就是,此时sayName()是共享型的,person1和person2访问的是同一个sayName函数。
好吧今天就先写到这里,明天继续补上,不然寝室该停电了,那就恐怖了,以上所写是对《JavaScript高级程序设计》这本书就行了提炼和少许自己的见解,如果大家有什么不理解的欢迎讨论,当然更建议大家去买这本书(纸质书),我刚刚看了2天,就觉得受益匪浅,好了,撤了。
大家都知道在js中可以用Object构造函数和对象字面量这两种方式创建对象
//利用Object构造函数创建对象 varperson=newObject(); person.name="DJL"; person.age=22; //利用对象字面量创建对象 varperson2={ name:"DJL", age:22 } alert(person.name);//DJL alert(person2.name);//DJL
但是上诉两种创建对象的方法都有一个明显的缺点那就是使用同一个接口创建很多对象会产生很多重复的代码。为了解决这个问题js引入了工厂模式:
functioncreatePerson(name,age,job){ varo=newObject(); o.name=name; o.age=age; o.job=job; o.sayName=function(){ alert(this.name); } returno; }
varperson1=createPerson("DJL1",22,"student1");
varperson2=createPerson("DJL2",22,"student2");
alert(typeofcreatePerson("DJL2",22,"student2"));//object
这样我们在利用createPerson这个函数接口创建很多对象时,就不用每个都要去写o.name=name;o.age=age;这些重复的代码。工厂模式创建对象就在于在这个函数接口内部利用Object构造函数又创建了一个新的对象,然后return出来。但是,但是,但是,这种模式也是有问题的-----你怎么用instanceof,即你怎么知道某个对象的具体类型,这样吗
alert(person1instanceofcreatePerson);//这肯定是false啦
为了解决这个问题,构造函数模式出来了
functionCreatePerson(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=function(){
alert(this.name);
}
}
varperson1=newCreatePerson("DJL1",22,"student1");
varperson2=newCreatePerson("DJL2",22,"student2");
alert(person1instanceofCreatePerson);//true
与工厂模式不同的是:1没有显示的创建新对象2直接将属性和方法赋值给了this对象3没有return语句4函数名首字母大写
要创建CreatePerson的实例必须要使用关键字new。以这种方式新建对象会经历如下有如下4个过程
1创建新的对象
2将构造函数的作用域赋给新对象(因此this就指向了新对象)
3执行构造函数中的代码
4返回新对象
利用构造函数模式,我们可以将来将他的实例标识为一种特定的类型。然而这种模式也是有缺点的,上例中我们创建了person1和person2这两个实例,有相同的方法名sayName,但是这两个同名函数却不是相等的
alert(person1.sayName==person2.sayName)//false
但是有时我们同一个构造函数不同实例中的同名函数来共同完成一件事情怎么办,下面这是一种办法
functionCreatePerson(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=sayName;
}
functionsayName(){
//toDo
}
varperson1=newCreatePerson("DJL1",22,"student1");
varperson2=newCreatePerson("DJL2",22,"student2");
我们把sayName函数的定义转移到了构造函数外部,而在构造函数内部我们把sayName设置成了全局变量。这样person1和person2就共享了在全局域中定义的sayName()函数。这样做确实解决了共享性问题,但是如果有很多个这样的函数呢,那边要定义多个全局函数,那么封装性就不言而喻了。为了解决这个问题,原型模式就脱颖而出了。
我们创建的每一个函数都有一个prototype属性,该属性是一个指针,指向一个对象。这个对象包含了所有实例共享的属性和方法。使用原型对象的好处就是可以让所有对象实例共享它所包含的属性和方法。我们不必在构造函数中去定义对象实例的信息,而是可以将这些信息添加到原型对象中。
functionCreatePerson(){
}
CreatePerson.prototype.name="DJL";
CreatePerson.prototype.age=22;
CreatePerson.prototype.job="student";
CreatePerson.prototype.sayName=function(){
alert(this.name);
}
varperson1=newCreatePerson();
person1.sayName();
varperson2=newCreatePerson();
person2.sayName();
alert(person1.sayName==person2.sayName);//true
此时我们仍然可以通过CreatePerson这个构造函数来创建实例,并且能够访问sayName这个函数,与构造函数模式的区别就是,此时sayName()是共享型的,person1和person2访问的是同一个sayName函数。
好吧今天就先写到这里,明天继续补上,不然寝室该停电了,那就恐怖了,以上所写是对《JavaScript高级程序设计》这本书就行了提炼和少许自己的见解,如果大家有什么不理解的欢迎讨论,当然更建议大家去买这本书(纸质书),我刚刚看了2天,就觉得受益匪浅,好了,撤了。
相关文章推荐
- c#解析Json数据
- JS 页面加载触发事件 document.ready和window.onload的区别
- js版根据经纬度计算多边形面积(墨卡托投影)
- javascript之闭包深入理解(一)
- javascript之闭包深入理解(二)
- 【下班后学js】判断传入的两个数组是否相似
- JavaScript与DOM(下)
- js操作json
- 2016.01.02JS滚轮事件详解
- JavaScript系列(一 :初识)
- seajs模块化开发初探
- JS 变量提升
- JS实现八种焦点轮播图(下)
- JavaScript与DOM(上)
- JS实现八种焦点轮播图(上)
- 《高性能javascript》一书要点和延伸(下)
- jstorm安装配置
- JS将毫秒时间戳转换成合适的时间字符串
- JS实现-语句
- js中的匿名函数