创建对象:对象的抽象与封装
1.字面量创建
产生大量重复代码
2、 工厂模式
这种方式本质上是将创建对象的过程进行了封装,本质并没有改变。
优点:通过将创建对象的方法封装起来,避免重复代码产生。
缺点:1.创建出来的所有对象类型都是Object类型,没有办法知道对象到底是Person还是Dog
2.封装性比较差,函数声明和工厂函数单独声明
3.占用过多内存
//工厂函数创建的对象,对象有自己的属性和方法
function newPerson(name,age,gender){
var p=new Object();
p.name=name;
p.age=age;
p.gender=gender;//属性
p.sayName=function(){
console.log(this.name);//方法
};
return p;
}
var p1=newPerson('zs',12,'男');
var p2=newPerson('ls',15,'女');
console.log(p1);
console.log(p2);
p1.sayName();
p2.sayName();//方法
console.log(typeof p1);
function newDog (name, age, gender) {
var d = new Object();
d.name = name;
d.age = age;
d.gender = gender;
d.sayName = function () {
console.log("汪汪的名字是" + this.name);
}
return d;
}
var d1 = newDog("wangcai", 2, "男");
console.log(d1);
d1.sayName();
console.log(typeof p1);
console.log(typeof d1);
结果:
{ name: 'zs', age: 12, gender: '男', sayName: [Function (anonymous)] }
{ name: 'ls', age: 15, gender: '女', sayName: [Function (anonymous)] }
zs
ls
object
{
name: 'wangcai',
age: 2,
gender: '男',
sayName: [Function (anonymous)]
}
汪汪的名字是wangcai
object
object
3.构造函数模式
构造函数模式是为了解决工厂模式中关于对象均为object类型这个问题
优点:可以区分每个类
缺点:1…每个方法都要在每个实例上创建一遍,没有必要
2.虽然可以将方法提取出来,提取到全局范围内,然后引用传递给对象中的函数属性,但是全局函数太多的话,体现不了类的封装性
function Person (name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = function () {
console.log(this.name);
}
}
var p1 = new Person('terry', 23, '男');
p1.sayName();
console.log(p1);
console.log(typeof p1);
结果:
terry
Person {
name: 'terry',
age: 23,
gender: '男',
sayName: [Function (anonymous)]
}
object
使用new操作符调用构造函数创建对象实际上经历了如下几个步骤:
1.创建一个新对象
2.将构造函数的作用域赋给新对象(this指向这个新对象)
3.执行构造函数中的代码
4.返回新对象 这种创建对象的方法可以将实例标识为一种特定类型(例如Person类型)
4.原型模式
优点:对于共享的属性 共享函数使用这种方式创建是非常合适的
缺点:但是对于引用类型的数据就不太好了
function Person(){};
Person.prototype.name="zs";
Person.prototype.age=12;
Person.prototype.gender="男";
Person.prototype.sayName=function(){
console.log(this.name);
}
var p1=new Person();
var p2=new Person();
p1.sayName();
p2.sayName();
结果:
zs
zs
5.组合模式
原型模式+构造函数模型
将对象属性封装在构造函数中,体现独特性
将对象方法封装在原型中,多个实例共享方法构造函数和原型链模式混合的特点:
1.可以区分不同类型的对象
2.体现封装
3.不占用过多内存
4.支持不共享属性
// 家族共享的属性和方法放到原型对象中,
//构建对象过程+对象私有的属性方法放到构造函数中
//将方法定义在构造函数的原型中,那么实例对象就可以访问其构造函数原型中的方法,
//原型中的方法是所有的实例对象共享的。
function Person(name,age,gender){
this.name=name,
this.age=age,
this.gender=gender,
this.likes=[]
}
Person.prototype={
constructor:Person,
sayName:function(){
console.log(this.name);
}
}
var p1=new Person('larry',12,'男');
p1.likes.push('打篮球')
var p2=new Person('terry',23,'男');
p2.likes.push('踢足球')
console.log(p1);
console.log(p2);
结果:
Person { name: 'larry', age: 12, gender: '男', likes: [ '打篮球' ] }
Person { name: 'terry', age: 23, gender: '男', likes: [ '踢足球' ] }