04_原型链

原型

原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。

    // Car.prototype ==> {} 祖先
    Car.prototype.name = 'GTR';
    Car.prototype.color = 'silver';
    // Car.prototype = {
    //     name = 'GTR';
    //     color = 'silver';
    // }

    function Car(owner) {
        this.owner = owner;
    }

    var car = new Car('TT');
    Dog.prototype.name = 'laifu';
    function Dog() {
        // var this = { __proto__ : Dog.protype }
        // 准确:this = Object.create(Dog.prototype);
        // return this;
    }
    var laifu = new Dog();
    Dog.prototype = {
        name : 'wangcai'
    }
    console.log(laifu.name);  // laifu
  1. 利用原型特点和概念,可以提取共有属性。
  2. 构造函数如何查看原型 ==> prototype
  3. 对象如何查看原型 ==> 隐式属性:__proto__
  4. 对象如何查看对象的构造函数 ==> constructor
    function Dog(name, breed) {
        this.name = name;
        this.breed = breed;
    }

    var wangcai = new Dog('wangcai', 'ShibaInu');
    var laifu = new Dog('laifu', 'TuGou');

    console.log(Dog.prototype);
    console.log(wangcai.__proto__);
    console.log(Dog.prototype === wangcai.__proto__);  // true

    console.log(Dog.prototype.constructor);
    console.log(wangcai.constructor);
    console.log(Dog.prototype.constructor === wangcai.constructor);  // true

原型链

    Grand.prototype.lastName = 'Li';
    function Grand() {

    }

    var grand = new Grand();

    Father.prototype = grand;
    function Father() {
        this.name = 'bai';
        this.composition = {
            no1 : '侠客行'
        }
    }

    var father = new Father();

    Son.prototype = father;
    function Son() {
        this.hobbit = 'compose';
    }

    var son = new Son();

    console.log(son.lastName);
    son.composition.no1 = '将进酒';  // 引用值修改
    son.composition.no2 = '蜀道难';  // 引用值添加
    console.log(son.composition);
    console.log(father.composition);

绝大多数对象最终都会继承自Object.prototype

    var obj = Object.create(null);
    // 以null为原型创建一个对象
    console.log(obj);  // 一个完全为空的对象

    obj.__proto__ = { name : 'sunny' }
    console.log(obj.name);  // undefined

    // 原型是隐式的内部属性,人为设置是不具有继承特性的。

继承

  1. 传统形式 ==> 原型链继承

    • 过多的继承了没用的属性
  2. 借用构造函数

    • 不能继承借用构造函数的原型
    • 每次构造函数都要多走一个函数
        function Person(name, age, gender) {
            this.name = name;
            this.age = age;
            this.gender = gender;        
        }
    
        function Student(name, age, gender, tel, grade) {
            Person.call(this, name, age, gender);
            // 把Person里的this指向改变为Student里的this
            // this.name = name;
            // this.age = age;
            // this.gender = gender;
            this.tel = tel;
            this.grade = grade;
        }
    
  3. 共享原型

    • 不能随便改动自己的原型
        Father.prototype.lastName = 'Li';
    
        function Father() {}
        function Son() {}
    
        Son.prototype = Father.prototype
        var son = new Son();
    
        // 抽象成函数方法
        function inherit(Target, Origin) {
            Target.prototype = Origin.prototype;
        }
        inherit(Son, Father);
        var son = new Son();
    
        // 缺点:
        Son.prototype.key = 'value';
        // Son和Father都继承到key属性了
    
  4. 圣杯模式

            Father.prototype
             /          \
            /            \
        Father      function Fn() {}  
                    Fn.prototype = Father.prototype
                            \
                             \
                        Son.prototype = new Fn()
    
        // 抽象成函数
        function inherit(Target, Origin) {
            function Fn() {}
            Fn.prototype = Origin.prototype;
            Target.prototype = new Fn();
            Target.prototype.constructor = Target;
            // 防止new Target()生成的对象的constructor指向紊乱
    
            Target.prototype.uber = Origin.prototype;
            // 可以人为标记Target真正继承的是Origin,而不是中间层的Fn
        }
    
        Father.prototype.lastName = 'Li';
        function Father() {}
        function Son() {}
    
        inherit(Son, Father);
        var son = new Son();
        var father = new Father();
    
        Son.prototype.key = 'value';
        console.log(son.key);  // value
        console.log(father.key);  // undefined
    
        var inherit = (function() {
            var Fn = function () {}
            // 形成闭包后,Fn就可以看作是一个私有变量。
            return function (Target, Origin) {
                Fn.prototype = Origin.prototype;
                Target.prototype = new Fn();
                Target.prototype.constructor = Target;
                Target.prototype.uber = Origin.prototype;
            }
        }());
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值