JS 怎样模拟类的特性

427 阅读1分钟

function Animal(){}

function Dog(){}

1.实现 Dog 继承 Animal

Dog.prototype = Object.create(Animal.prototype)

背景知识:
    要实现 Dog 继承 Animal, 
    就是要实现 new Dog() instanceof Animal 为真
    就是要实现 new Dog().__proto__.__proto__ === Animal.prototype
    即实现 Animal.prototype 在 new Dog() 的原型链上
实现过程:
    根据js原型链的相关知识, 有 new Dog().__proto__ === Dog.prototype
    要实现继承, 就可以令 Dog.prototype.__proto__ === Animal.prototype
    也就是 Dog.prototype = Object.create(Animal.prototype)
// 测试代码(直接在浏览器控制台中运行):
    
    function Animal(){}
    function Dog(){}
    Dog.prototype = Object.create(Animal.prototype);
    console.log(new Dog() instanceof Animal);//结果为 true

2.实现 DogAnimal 类之间的多态,方法重写等

// 测试代码(直接在浏览器控制台中运行):

    function Animal(){}
    function Dog(){}
    Object.defineProperties(Animal.prototype,{
        name:{
            value(){
                return 'Animal';
            }
        },
        say:{
            value(){
                return 'I’m ' + this.name();
            }
        }
    });
    
    //子类Dog继承父类Animal中的方法
    Dog.prototype = Object.create(Animal.prototype);
    console.log(new Dog().say());//结果为 I’m Animal
    
    //子类Dog重写父类Animal的name方法
    Dog.prototype = Object.create(Animal.prototype,{
        name:{
            value(){
                return 'Dog';
            }
        }
    });
    console.log(new Dog().say());//结果为 I’m Dog

3.完善类的模拟

// 测试代码(直接在浏览器控制台中运行):

    function Animal(){}
    function Dog(){}
    Dog.prototype = Object.create(Animal.prototype);
    console.log(Dog.prototype.constructor);//结果为 ƒ Animal(){}
    
    //上面的这个输出是不对的, 结果应该是 ƒ Dog(){}, 解决方法
     Dog.prototype = Object.create(Animal.prototype,{
        constructor:{
            value:Dog,
            enumerable:false
        } 
     });
     console.log(Dog.prototype.constructor);// 结果为 ƒ Dog(){}