详细分析Javascript中创建对象的四种方式
前言
使用Javascript创建对象的方式有很多,现在就来列举一下其中的四种方式,并且罗列出了每种方式的优缺点,可以让大家进行选择使用,下面来看看。
工厂模式
functioncreatePerson(name,age){
varobj=newObject();
obj.name=name;
obj.age=age;
returnobj;//一定要返回,否则打印undefined:undefined
}
varperson1=newcreatePerson('Young',18);
console.log(person1.name+':'+person1.age);
优点:工厂模式可以解决创建多个相似对象
缺点:没有解决对象识别问题(怎样确定一个对象的类型)
构造函数模式
functionPerson(name,age){
this.name=name;
this.age=age;
}
varperson1=newPerson('Young',18);
console.log(person1.name+':'+person1.age);
在说优缺点之前,先来说说她本身的一点小故事吧
将构造函数当做函数使用
functionPerson(name,age){
this.name=name;
this.age=age;
this.sayName=function(){
returnthis.name;
}
}
//当做构造函数使用
varperson1=newPerson('Young',18);
person1.sayName();
console.log(person1.name+':'+person1.age);
//当做普通函数调用
Person('Wind',18);
console.log(window.sayName());
//在另一个作用域中调用
varobj=newObject();
Person.call(obj,'bird',100);
console.log(obj.sayName());
构造函数优缺点
优点:可以将它的实例标识为一种特定类型
缺点:每个方法都要在每个实例上重新创建一遍。当然你也可以这样改:
functionPerson(name,age){
this.name=name;
this.age=age;
this.sayName=sayName;
}
functionsayName(){
returnthis.name;
}
改为调用全局函数,这样一来毫无封装性可言。。。接下来的原型模式可以弥补这个的不足
原型模式
functionPerson(){
}
Person.prototype.name='Young';
Person.prototype.age=18;
Person.prototype.sayName=function(){
returnthis.name;
}
varperson1=newPerson();
console.log(person1.sayName());
varperson2=newPerson();
console.log(person1.sayName());
alert(person1.sayName===person2.sayName);
//person1和person2访问的是同一组属性的同一个sayName()函数
虽然可以通过对象实例访问保存在原型中的值,但却不能通过实例对象重写原型中的值
functionPerson(){
}
Person.prototype.name='Young';
Person.prototype.age=18;
Person.prototype.sayName=function(){
returnthis.name;
}
varperson1=newPerson();
varperson2=newPerson();
person1.name='Wind';
console.log(person1.sayName());//Wind
console.log(person2.sayName());//Young
alert(person1.sayName==person2.sayName);//true
在我们调用person1.sayName的时候,会先后执行两次搜索,解析器先确定实例person1是否有sayName的属性,有则调用自己的属性,没有则搜索原型中的属性。
functionPerson(){
}
Person.prototype.name='Young';
Person.prototype.age=18;
Person.prototype.sayName=function(){
returnthis.name;
}
varperson1=newPerson();
varperson2=newPerson();
person1.name='Wind';
console.log(person1.sayName());//Wind
console.log(person2.sayName());//Young
deleteperson1.name;
console.log(person1.sayName());//Young
console.log(person2.sayName());//Young
使用hasOwnPropertyType方法可以检测一个属性是存在与原型中还是存在于实例中,该方法是从Object继承来的,实例中为true,原型中为false。
枚举对象上的实例属性用Object.keys()方法
functionPerson(){
}
Person.prototype.name='Young';
Person.prototype.age=18;
Person.prototype.sayName=function(){
returnthis.name;
}
varkeys=Object.keys(Person.prototype);
console.log(keys);//["name","age","sayName"]
原型模式优缺点
优点:不用每个方法都要在每个实例上重申一遍
缺点:很少有人单独使用原型模式地。。问题详列
functionPerson(){
}
Person.prototype={
constructor:Person,
name:'Young',
age:18,
friends:['Big','Pig'],
sayName:function(){
returnthis.name;
}
};
varp1=newPerson();
varp2=newPerson();
p1.friends.push('Mon');
console.log(p1.friends);//["Big","Pig","Mon"]
console.log(p2.friends);//["Big","Pig","Mon"]
正是因为实例一般都要有自己的属性,而我们这里将他放在了Person.prototype中,所以随着p1的修改,整个实例包括原型都修改了。那么,我们可以组合使用构造函数模式和原型模式。
组合使用构造函数模式和原型模式
functionPerson(name,age){
this.name=name;
this.age=age;
this.friends=['Big','Pig'];
}
Person.prototype={
sayName:function(){
returnthis.name;
}
};
varp1=newPerson('Young',18);
varp2=newPerson('Wind',78);
p1.friends.push('Raganya');
console.log(p1.friends);//["Big","Pig","Raganya"]
console.log(p2.friends);//["Big","Pig"]
console.log(p1.friends==p2.friends);//false
console.log(p1.sayName==p2.sayName);//true
这种模式是目前使用最广泛、认同度最高的一种创建自定义类型的方法。是用来定义引用类型的一种默认模式。
总结
以上就是关于分析Javascript中创建对象方式的全部内容,通过这篇文章为大家总结的四种方式和其优缺点,希望可以对大家学习使用Javascript能有所帮助。