JavaScript高级日记(三)面向对象高级

目录

对象创建模式

继承模式


对象创建模式

方式一:Object构造函数模式

先创建空Object对象,再动态添加属性/方法;适用于起始时不确定对象内部数据的场景;缺点是语句太多

var p=new Object();
p.name='tml';
p.age=12;
p.setName=function(name){
    this.name=name;
}
p.setName('zy');
console.log(p.name,p.age);//zy 12

方式二:对象字面量模式

使用{ }创建对象,同时指定属性/方法;适用于起始时对象内部数据确定的场景;缺点是如果创建多个对象,有重复代码

var p1={
    name:'tml',
    age:12,
    setName:function(name){
        this.name=name;
    }
}
var p2={
    name:'tml',
    age:12,
    setName:function(name){
        this.name=name;
    }
}//创建多个对象代码重复
p1.setName('ly');
console.log(p1.name,p1.age);//ly 12

方式三:工厂模式

通过工厂函数(返回一个对象的函数)动态创建对象并返回;适用于需要创建多个对象的场景;缺点是对象没有一个具体的类型,都是Object类型

function createPerson(name,age){
    var obj={
        name:name,
        age:age,
        setName:function(name){
            this.name=name;
        }
    }
    return obj;
}
var p1=createPerson('tml',21);
var p2=createPerson('ly',22);

方式四:自定义构造函数模式

自定义构造函数,通过new创建对象;适用于需要创建多个类型确定的对象的场景;缺点是每个对象都有相同的数据,浪费内存

function Person(name,age){
    this.name=name;
    this.age=age;
    this.setName=function(name){
        this.name=name;
    }
}
function Student(name,price){
    this.name=name;
    this.price=price;
    this.setName=function(name){
        this.name=name;
    }
}
var p=new Person('tml',21);
var s=new Student('ly',90);
console.log(p instanceof Person);//true
console.log(s instanceof Student);//true

方式五:构造函数+原型

自定义构造函数,属性在函数中初始化,方法添加到原型上;适用于需要创建多个类型确定的对象的场景

function Person(name,age){
    // 在构造函数中只初始化一般函数
    this.name=name;
    this.age=age;
}
Person.prototype.setName=function(name){
    this.name=name;//this是实例化对象
}
var p=new Person('tml',21);
console.log(p);
// Person {name: "tml", age: 21}
// name: "tml"
// age: 21
// __proto__:
// setName: ƒ (name)
// constructor: ƒ Person(name,age)
// __proto__: Object

继承模式

原型链继承:

1.定义父类型构造函数

2.给父类型的原型添加方法

3.定义子类型的构造函数

4.创建父类型的对象赋值给子类型的原型

5.将子类型原型的构造属性设置为子类型

6.给子类型原型添加方法

7.创建子类型的对象:可以调用父类型的方法

关键:子类型的原型为父类型的一个实例对象

// 父类型
function Supper(){
    this.supProp="Supper property";
}
Supper.prototype.showSupperProp=function(){
    console.log(this.supProp);
}
// 子类型
function Sub(){
    this.subProp="Sub property";
}
// 子类型的原型为父类型的一个实例对象
Sub.prototype=new Supper();
// (原本Object是sub原型的父亲,现在supper的原型是父亲了,Object是祖父,一样可以访问到)
Sub.prototype.showSubProp=function(){
    console.log(this.subProp);
}
var sub=new Sub();
sub.showSupperProp();//Supper property
sub.showSubProp();//Sub property
console.log(sub.constructor);//Supper(){this.supProp="Supper property";}
// 实例的constructor来自实例指向的prototype对象中的constructor
// 让子类型原型的constructor指向子类型
Sub.prototype.constructor=Sub;
console.log(sub.constructor);//Sub(){this.subProp="Sub property";}
/**弹幕
 * 1. 这里可以补充一下constructor 的作用:constructor中文就是构造函数
 * 2. 其作用是让某个构造函数产生的 所有实例对象(比如f) 能够找到他的构造函数(比如Fun),用法就是f.constructor
 * 3. 此时实例对象里没有constructor 这个属性,于是沿着原型链往上找到Fun.prototype 里的constructor,并指向Fun 函数本身
 * 4. 由于这里的继承是直接改了构造函数的prototype 的指向,所以在 sub的原型链中,Sub.prototype 没有constructor 属性,反而是看到了一个super 实例
 * 5. 这就让sub 实例的constructor 无法使用了。为了他还能用,就在那个super 实例中手动加了一个constructor 属性,且指向Sub 函数
*/

借用构造函数继承(假继承):

1.定义父类型构造函数

2.定义子类型构造函数

3.在子类型构造函数中调用父类型构造

关键:在子类型构造函数中通用call()调用父类型构造函数

function Person(name,age){
    this.name=name;
    this.age=age;
}
function Student(name,age,price){
    Person.call(this,name,age);//相当于 this.Person(name,age); 临时让Person成为this的方法调用
    // this.name=name;
    // this.age=age;
    this.price=price;
}
var s=new Student('tml',21,12000);
console.log(s.name,s.age,s.price);

原型链+借用构造函数的组合继承:

1.利用原型链实现对父类型对象的方法继承

2.利用super()借用父类型构建函数初始化相同属性

function Person(name,age){
    this.name=name;
    this.age=age;
}
Person.prototype.setName=function(name){
    this.name=name;
}
Person.prototype.setAge=function(age){
    this.age=age;
}
function Student(name,age,price){
    Person.call(this,name,age);//为了得到属性
    this.price=price;
}
Student.prototype=new Person();//使其能看到父类型的方法
Student.prototype.constructor=Student;//修正constructor属性
Student.prototype.setPrice=function(price){
    this.price=price;
}
var s=new Student('tml',18,8000);
s.setAge(21);
s.setPrice(12000);
console.log(s.name,s.age,s.price);//tml 21 12000

(视频:B站尚硅谷)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值