js创建对象的多种方法教程
方法共有:object构造函数或对象字面量 ,object.create() ,工厂模式,构造函数模式 ,原型模式 ,组合使用构造函数模式和原型模式 ,动态原型的创建 ,寄生构造函数模式 ,寄生构造函数模式 ,稳态构造函数模式
1>object构造函数或对象字面量
缺点是使用同一个接口创建很多对象,会产生大量重复的代码
对象字面量是一个表达式,这个表达式的每次运算都会创建并初始化一个新的对象(例:在一个重复调用的函数中的函数体使用对象直接量,创建很对新的对象)
var person=new object(); person.name="shisha"; console.log(person); var person={name:"shisha"} console.log(person);
2>object.create()
创建一个新对象,其中第一个参数为这个对象的原型,第二个参数对对象的属性进行进一步描述(与object.defineproperty()的第二个参数一致),返回在指定原型对象上添加属性后的对象。它会失去原来对象的属性访问
var base=function(){ this.a=2; } var obj1=object.create(base); console.log(obj1.a);//undefine var obj2=new base(); console.log(obj2.a);//2 var o = object.create({}, { p: { value: 42 } }); console.log(o);//{p:42}
3>工厂模式:用函接数来封装以特定接口创建对象的细节,解决了创建多个相似对象的问题
缺点:没有解决对象的识别问题(对象的类型)
function createperson(name,age,job){ var o=new object(); o.name=name; o.age=age; o.job=job; o.sayname=function(){ alert(this.name) } return o; } var person1= createperson("shihsha",12,"web"); var person2= createperson("ss",21,"java");
4>构造函数模式
构造函数可以用来创建特定类型的对象
缺点:每个方法都有在实例上重新创建一次,他们的方法不是同一个function实例
function person(name,age,job){ this.name=name; this.age=age; this.job=job; this.sayname=function(){ alert(this.name) } //this.sayname=new function("alert(this.name)");与声明函数在逻辑上等价 } var person1= new person("shihsha",12,"web"); var person2= new person("ss",21,"java");
与工厂模式的不同:
没有显示的创建对象
直接将属性和方法赋给了this对象
没有return语句
要创建实例必须使用new操作符
可以使用instanceof操作符检测对象类
5>原型模式
我么创建的每一个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法,也就是说不必在构造函数中定义对象实例的信息,而是将这些信息直接添加到原型对象中。
缺点:它省略了为构造函数传递初始化参数这一环节,结果所有实例在默认情况下都将取得相同的属性值.
它最大的问题是由他的共享属性导致的,对于包含基本值的属性也可以,在实例上添加一个同名属性,可以隐藏原型中对应的值,但是对于引用类型来说问题比较突出,他们会相互影响。
function person(){ } person.prototype.name="shisha"; person.prototype.age=21; person.prototype.job="web"; person.prototype.sayname=function(){ alert(this.name); } var person1=new person(); 问题: function person(){ } person.prototype={ name:"shisha", age:21, job:"web", friends:["ss","zz"] } var person1=new person(); var person2=new person(); person1.friends.push("vv") console.log(person1.friends); console.log(person2.friends);
6>组合使用构造函数模式和原型模式(最常见的方式)
构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性。每个实例都会有自己的一份实例属性的副本,但同时又共享着对方法的引用,最大程度的节省内存,它支持向构造函数传递参数
function person(name,age,job){ this.name=name; this.age=age; this.job=job; this.friends=["ss","zz"] } person.prototype.sayname=function(){ alert(this.name); } var person1= new person("shihsha",12,"web"); var person2= new person("ss",21,"java"); person1.friends.push("vv") console.log(person1.friends);//["ss", "zz", "vv"] console.log(person2.friends);//["ss", "zz"]
7>动态原型的创建
可以通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型
function(name,age,job){ this.namn=name; this.age=age; this.job=job; if(typeof this.sayname !="function"){ person.pertotype.sayname=function(){ alert(this.name) } } } var person1= new person("shihsha",12,"web");
8>寄生构造函数模式
前面几个模式都不合适的情况下可以使用这个模式,这个模式除了使用new之外,其余的和工厂模式是一模一样的
function person(name,age,job){ var o=new object(); o.name=name; o.age=age; o.job=job; o.sayname=function(){ alert(this.name) } return o; } var person1=new person("shihsha",12,"web");
9>稳态构造函数模式
上一篇: MySQL optimization