本文实例分析了JS常见构造模式。分享给大家供大家参考,具体如下:
1.工厂模式
没有解决对象识别的问题。因为函数内部使用了new Object来创建对象
function Factory(name,age){ var o=new Object(); o.name=name; o.age=age; o.what=what;//用函数引用的方式消除重复创建相同函数的弊端,节省资源.函数引用可以修改this的指向,函数调用不可以! return o;}what=funciton(){ alert(this.name+this.age);}var o=Factory("12",12);o.what();//what中的this指向o对象
这时候的constructor是Object,同时所有通过工厂模式返回的对象都是Object类型,所以instanceof
操作符没有意义
console.log(o.constructor);//打印function Object() { [native code] }console.log(o instanceof Object);//而且这时候所有的对象都是Object类型的
2.构造函数模式
function Person(name,age){this.name=name;this.age=age;this.sayName=function(){ alert(this.name);}//相当于this.sayName=new Function("alert(this.name)")}var p1=new Person("xx",12);var p2=new Person("yy",13);alert(p1.sayName==p2.sayName)//内存地址不一样!返回false
构造函数相比工厂模式的优点在于能够正确的返回对象的类型,instanceof
返回正确的结果。缺点在于如果向上面那样,那么在每一个对象上面都要有一个sayName方法,而且这些sayName方法不是同一个Function实例,因为ECMAScript中函数是对象,因此每定义一个函数,也就是实例化了一个对象!
对上面的方法进行优化:
function Person(name,age){this.name=name;this.age=age;this.sayName=sayName;//函数引用的方法,共享了同一个sayName,p1,p2的内存地址一样,p1.sayName==p2.sayName返回true}function sayName(){alert(this.name);}
缺点:全局函数sayName只能被某个对象调用p1.sayName
,让全局函数名不副实;如果对象要定义很多方法,那么就要定义很多的全局函数,所以自定义的引用类型没有封装性可言
3.原型模式
(1)无法通过构造函数参数向原型属性动态传值,后果就是:没有个性,改变原型属性的值,所有的实例都会受到干扰!
(2)当原型属性的是引用类型的时候,如果在一个对象实例上修改属性,将会影响所有实例!
总之一句话:牵一发而动全身(包括属性和引用类型的值)是原型模式的特点。但是相比于构造函数类型,原型类型满足
person1.sayName===person2.sayName//两者的引用是一样的
4.构造函数原型模式
用构造函数定义个性,用原型模式定义共性
function Person(name,age){ this.name=name; this.age=age; this.friends=['liangklfang','qinliang'];}//用原型定义共性Person.prototype={ constructor:Person, sayName:function() { console.log(this.name); }}var person1=new Person('liangklfang',"12");var person2=new Person('liangklf',"14");console.log(person1.sayName===person2.sayName);//共性是函数,打印trueconsole.log(person1.friends===person2.friends);//friends是个性,打印false
新闻热点
疑难解答
图片精选