Javascript 面向对象编程

本文深入讲解JavaScript面向对象编程,探讨封装、构造函数继承等概念。介绍构造函数模式、原型模式及混合模式,详解如何实现继承并保持内存效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Javascript 面向对象编程(一):封装

Javascript面向对象编程(二):构造函数的继承

Javascript面向对象编程(三):非构造函数的继承


 /**
     * 封装
     *
     * 为了解决从原型对象生成实例的问题,Javascript提供了一个构造函数(Constructor)模式。
     * 所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,
     * 就能生成实例,并且this变量会绑定在实例对象上。
     *
     * Javascript规定,每一个构造函数都有一个prototype属性,指向另一个对象。
     * 这个对象的所有属性和方法,都会被构造函数的实例继承。
     * 这意味着,我们可以把那些不变的属性和方法,直接定义在prototype对象上。
     */
//    function Cat(name,color){
//        this.name = name;
//        this.color = color;
//    }
//    Cat.prototype.type = "猫科动物";
//    Cat.prototype.eat = function(){alert("吃老鼠")};

    /**
     * 构造函数的继承
     *
     * 怎样才能使"猫"继承"动物"呢?
     * 第一种方法也是最简单的方法,使用call或apply方法,将父对象的构造函数绑定在子对象上,即在子对象构造函数中加一行:
     * Animal.apply(this, arguments);
     */
//    function Animal(){
//        this.species = "动物";
//    }
//    function Cat(name,color){
//        this.name = name;
//        this.color = color;
//    }
//    function Cat(name,color){
//        Animal.apply(this, arguments);
//        this.name = name;
//        this.color = color;
//    }
//    var cat1 = new Cat("大毛","黄色");
//    alert(cat1.species); // 动物
    /**
     * 第二种方法更常见,使用prototype属性,
     * 我们将Cat的prototype对象指向一个Animal的实例
     * Cat.prototype = new Animal();
       Cat.prototype.constructor = Cat;
       var cat1 = new Cat("大毛","黄色");
       alert(cat1.species); // 动物

     第三种方法是对第二种方法的改进,直接继承Animal.prototype。
     Cat.prototype = Animal.prototype;
       Cat.prototype.constructor = Cat;
       var cat1 = new Cat("大毛","黄色");
       alert(cat1.species); // 动物
     与前一种方法相比,这样做的优点是效率比较高(不用执行和建立Animal的实例了),比较省内存。
     缺点是 Cat.prototype和Animal.prototype现在指向了同一个对象,那么任何对Cat.prototype的修改,
     都会反映到Animal.prototype。

     四、 利用空对象作为中介
     var F = function(){};
       F.prototype = Animal.prototype;
       Cat.prototype = new F();
       Cat.prototype.constructor = Cat;
     F是空对象,所以几乎不占内存。这时,修改Cat的prototype对象,就不会影响到Animal的prototype对象。
     可以将空对象作为中介封装为extend函数,很多库都有这个方法
     */


    /**
     * new操作符具体干了什么呢?
     * 1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
     2、属性和方法被加入到 this 引用的对象中。
     3、新创建的对象由 this 所引用,并且最后隐式的返回 this 。
     */

    /**
     * js面向对象,多种创建对象方法!
     * 1.对象字面量。
     * 2.创建Object实例
     * 2,构造函数模式
     3,原型模式
     4,混合构造函数和原型模式
     */

    function Super(){
        this.val = 1;
        this.arr = [1];
    }
    function Sub(){
        // ...
    }
    Sub.prototype = new Super();    // 核心

    var sub1 = new Sub();
    var sub2 = new Sub();
    sub1.val = 2;
    sub1.arr.push(2);
    console.log(sub1.val);    // 2
    console.log(sub2.val);    // 1

    console.log(sub1.arr);    // 1, 2
    console.log(sub2.arr);    // 1, 2
    var sub3 = new Sub();
    console.log(sub3.val);  //1
    // 原型对象的非引用属性属于每个对象的实例,原型对象的引用属性是所有实例共享的
    //修改sub1.arr后sub2.arr也变了,因为来自原型对象的引用属性是所有实例共享的。
    //这里的sub1.arr其实访问的是sub1.__proto__.arr,arr是一个数组对象,=指代的是一个内存地址的引用。
    //避免对象共享可以参考经典的extend()函数,很多前端框架都有封装的,就是用一个空函数当做中间变量


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值