JavaScript面向对象的程序设计学习

本文深入探讨了JavaScript中对象的创建方法,包括工厂模式、构造函数模式、原型模式和组合模式。同时,详细阐述了对象的继承机制,如原型链继承、经典继承(借用构造函数、伪造对象)和组合继承。通过实例展示了各种模式的优缺点,并提供了代码示例以帮助理解。
摘要由CSDN通过智能技术生成

对象的创建

工厂模式

使用普通字面量创建多个对象时,会产生大量的重复代码,为了解决该问题,引入了工厂模式。
工厂模式:通过将创建对象的方法封装起来,避免重复代码产生

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("小阵",1,"女");
var p2 =newPerson('李四',18,'男');
console.log(p1);//{ name: '小阵', age: 1, gender: '女', sayName: [Function] }
console.log(p2);

p1.sayName();//小阵
p2.sayName();

缺点:创建出来的所有的对象类型都是object,没有办法去识别对象(对象到底是person还是dog)

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;
}
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;
}

console.log(typeof p1);//object
console.log(typeof d1);//object

构造函数模式

//function sayName(){
//虽然可以将方法提取出来,提取到全局范围内,然后将引用传递给对象中的函数属性中,但是全局函数太多体现不了类的封装性
 //   console.log(this.name);
//}
function Person(name,age,gender){
    this.name=name;
    this.age=age;
    this.gender=gender;
    //this.sayName=sayName;
    this.sayName=function(){
    //每个方法都要在每个实例上重新创建一遍,没有这个必要
        console.log(this.name);
    }
}
//创建对象时要用new关键字
var p1=new Person("小阵",1,"女");
p1.sayName();//小阵

console.log(p1);//Person { name: '小阵', age: 1, gender: '女', sayName: [Function] }
//构造函数可以区分每个类

原型模式

function Person(){}
Person.prototype.name="小阵";
Person.prototype.age=1;
Person.prototype.gender="男";
Person.prototype.sayName=function(){
    console.log(this.name);
}
var p1=new Person();
var p2=new Person();
p1.sayName();//小阵
p2.sayName();//小阵
// 原型内的属性和方法是共享的

//对于共享属性,共享函数使用该方式创建是非常合适的,但是包含一些不共享的属性就很不友好
var p1=new Person();
p1.name="李四";//可以重新赋值
var p2=new Person();
p2.name="王五";
p1.sayName();//李四
p2.sayName();//王五
var p1=new Person();
p1.likes.push('画画');
console.log(p1.likes);//[ '读书', '摄影', '画画' ]
var p2=new Person();
console.log(p2.likes);//[ '读书', '摄影', '画画' ]
//对于引用类型的数据就不太好

组合模式:构造函数模式+原型模式

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("小阵",1,"男");
var p2=new Person("李四",2,"男");
p1.likes.push("读书");
p2.likes.push("踢足球");
console.log(p1);//Person { name: '小阵', age: 1, gender: '男', likes: [ '读书' ] }
console.log(p2);//Person { name: '李四', age: 2, gender: '男', likes: [ '踢足球' ] }
p1.sayName();//小阵

对象的继承

详细学习: 链接

原型链继承

调用对象的某一个方法或属性

//定义父类类型
function Animal(){
    this.name="animal";
}
Animal.prototype.sayName = function(){
    console.log(this.name);
}
//定义子类类型
function Dog(){
    this.color="黄色";
}
// 继承:将子类对象的原型指向父类对象的实例
Dog.prototype = new Animal();
//重点:让新实例的原型等于父类的实例

Dog.prototype.sayColor=function(){
    console.log(this.color);
}
var dog=new Dog();
console.log(dog);//Animal { color: '黄色' }
dog.sayName();//animal
dog.sayColor();//黄色

经典继承(借用构造函数、伪造对象)

function Animal(name,age){
    this.name=name;
    this.age=age;
    this.sayName=function(){
        console.log(this.name);
    }
}
Animal.prototype.sayAge=function(){
    console.log(this.age);
}
function Dog(name,age,color,type){
    //借用构造函数
    // 找到父类
    Animal.call(this,name,age);
    // 用.call()和.apply()将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行)
    this.color=color;
    this.type=type;
}

var dog= new Dog('芳芳',1,'yellow','金毛');
console.log(dog);
// dog.sayAge();//报错,因为是父类原型中的方法
dog.sayName();

组合继承

使用原型链实现对原型属性和方法的继承,而通过借用构造函数实现对实例属性的继承。

function Animal(name,age){
    this.name=name;
    this.age=age;
    this.Age=function(){
        console.log(this.age);
    }
}
Animal.prototype={
    constructor:Animal,
    sayName:function(){
        console.log("hello,my name is"+this.name);
    }
}
function Dog(name,age,type){
    //经典继承 属性
    Animal.call(this,name,age);
    this.type=type;
}
//原型链继承
Dog.prototype = new Animal();
Dog.prototype.constructor=Animal;
Dog.prototype.sayType=function(){
    console.log(this.type);
}
var dog= new Dog("花花",1,"二哈");
console.log(dog);//Animal { name: '花花', age: 1, Age: [Function], type: '二哈' }
dog.sayName();//hello,my name is花花
dog.sayType();//二哈
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值