JavaScript面向对象(高级)

1、对象的创建模式有哪些?

1、Object构造函数模式
2、对象字面量模式
3、工厂模式
4、自定义构造函数模式
5、构造函数和原型的组合模式

1.1 Object构造函数模式

*套路:先创建空Object对象再动态添加属性/方法
*适用场景:起始时不确定对象内部数据

缺点:语句太多

<script type="text/javascript">

    var p = new Object();
    p.name = 'Tom';
    p.age = 13;
    p.setName = function (name) {
        this.name = name;
    }
    //测试
    p.setName('Jak');
    console.log(p.name);//Jak
</script>

1.2 对象字面量模式

*套路:使用{}创建对象同时指定属性和方法‘
*使用场景:起始时对象 内部数据是确定的

缺点:
*问题:如果创建多个对象,有重复代 码
<script type="text/javascript">
    var p= {
        name : 'Tom',
        age : 13,
        setName:function (name) {
            this.name = name;
        }
    };

    //测试
    p.setName('Jak');
    console.log(p.name);//Jak

</script>

1.3工厂模式

1.3.1 什么是工厂函数?
工厂函数:返回一个对象的函数都可以称为工厂函数。

工厂模式:
*套路:通过工厂函数动态创建对象并返回
*使用场景:需要创建多个对象

缺点
*问题:**对象没有一个具体的类型,都是Object类型**
<script type="text/javascript">

function createPerson(name,age){//工厂函数
    var obj={//创建对象
        name:name,
        age:age,
        setName:function (name) {
            this.name = name;
        }
    }
    return obj;//返回对象
}
var p1=createPerson('Yom',19);//调用函数
var p2=createPerson('Tom',12);
console.log(p1,p2);//返回对象Object,在隐式原型__proto__下的setName不相等
</script>

1.4 自定义构造函数模式(平常使用的多,推荐)

*套路:自定义构造函数,通过new创建对象
*使用场景:需要创建多个类型确定的对象

缺点
*问题:每个对象都有相同的数据,浪费内存

<script type="text/javascript">
//定义类型
    function Person(name,age) {
        this.name = name,
            this.age = age,
            this.setName = function (name) {
                this.name = name;
            }
    }
function Student(name,age) {
    this.name = name,
        this.age = age,
        this.setName = function (name) {
            this.name = name;
        }
}

    //用new创建实例
    var p1=new Person('Yom',19);
    var p2=new Student('Tom',12);
    p1.name='Jvk';
    console.log(p1 instanceof Person);//true,即对象不再是单一的Object,
    console.log(p1.name,p2.name);//Jvk Tom

</script>

1.5构造函数和原型的组合模式

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

<script type="text/javascript">
    function Person(name,age) {
        this.name = name;
        this.age = age

    }
Person.prototype.setName=function (name) {//将方法绑定在构造函数的原型上
    this.name=name;//this
}
var p1=new Person('Tom',12);
    var p2=new Person('Jav',22);
console.log(p1,p2);返回对象,隐式原型上的构造器一样,说明p1和p2是在同一个对象上
    console.log(p1.name);//Tom
</script>

2、继承模式

2.1 继承模式有哪些?

1、原型继承
2、借用构造函数继承
3、原型和借用构造函数的组合继承

2.1原型继承

1、套路:
*1.1、定义父类型构造函数
*1.2.、给父类型的原型添加方法
*1.3、定义子类型的构造函数
*1.4、创建父类型的对象赋值给子类型的原型
*1.5、将子类型原型的构造属性设置为子类型
*.1.6、给子类型原型添加方法
*1.7、创建子类型的对象,可调用父类型的方法

2、关键
*子类型的原型为父类型的一个实例对象

<script type="text/javascript">
    //父类型
    function Supper() {
        this.supProp = 'supProp';
    }
 Supper.prototype.showSupper = function () {//将父类型的方法绑定到原型上
        console.log(this.supProp);
    }
    //子类型
    function SubPper() {
        this.subProp = 'subProp';
    }
//实现原型继承的核心代码如下:
    //1.实现继承的方法:子类型的原型为父类型的一个实例对象
    SubPper.prototype = new Supper();
    //2.将SubPper原型的constructor指向SubPper
    SubPper.prototype.constructor=SubPper;
//给子类型添加方法
    SubPper.prototype.showSubPper = function () {
        console.log(this.subProp);
    }
    //3.创建子类型的实例
    var sub = new SubPper();
    sub.showSupper();
    sub.toString();
    console.log(sub.constructor);
</script>

2.2借用构造函数继承

1、套路
*1、定义父类型的构造函数
*2、定义子类型的构造函数
*3、在子类型构造函数中调用父类型的构造函数

2、关键
*在子类型构造函数中通过call()调用父类型构造函数使用call()借用Person的属性执行

<script type="text/javascript">
function Person(name,age){
    this.name=name;
    this.age=age;
}
function Student(name,age,price) {
   Person.call(this,age,name);//this是子类型的实例。call是借用执行,相当于this.Person(name,age)
    // this.name=name;
    // this.age=age;
    this.price=price;
}
var s=new Student('Tom',12,100)
    console.log(s.name,s.age,s.price);
</script>

2.3原型和借用构造函数的组合继承

  • 1、利用原型链实现对父类型对象的方法继承
  • 2、利用call()借用父类型构造函数初始化相同属性
<script type="text/javascript">
    function Person(name,age){//创建父类型的构造函数
        this.name=name;
        this.age=age;
    }
    Person.prototype.setName=function (name) {
        this.name=name;
    }
    //重点一:
    function Student(name,age,price) {
        Person.call(this,age,name);//call是借用执行,相当于this.Person(name,age)
        // this.name=name;
        // this.age=age;
        this.price=price;
    }
    //重点二:
    //子类型的原型等于父类型的实例,为了看到父类型的方法和属性
    Student.prototype=new Person();
    //修正原型上的constructor
    Student.prototype.constructor=Student;

    Student.prototype.setPrice=function (price) {
        this.price=price;
    }

    var s=new Student('Tom',12,2222);
    s.setName('Emoo');
    s.setPrice(10000);
    console.log(s.name,s.age,s.price);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值