zoukankan      html  css  js  c++  java
  • JS继承

    继承是根据原型链实现的,一层层进行引用,当查找某个实例中的属性时,先在实例中进行查找,如果没有,再到原型中进行查找,如果原型还没有,在到prototype指向的父类模型中进行查找,像链条一样依次向上查找,直到找到该属性。

                    

    function Person() {
    
                    this.age = 12;
    
                }
    
                Person.prototype.Say = function () {
    
                    console.log("hello");
    
                }
    
                function Students() {
    
                    this.name = "aa";
    
                }
    
                Students.prototype.Learn = function () {
    
                    console.log("study");
    
                }
    
                Students.prototype = new Person();
    
     
    
                var student = new Students();
    
                student.Say(); // hello
    
                console.log(student.age); //12
    
                console.log(Students.prototype.constructor);  //function Person 实际上不是Students的原型的constructor被重写了,而是Students的原型指向了另一个对象(Person)的原型,而这个原型对象的constructor属性指向的是Person
    
                console.log(Students.prototype); //Person {age: 12}

    我们知道,所有引用类型都继承了object,而这个继承也是通过原型链实现的,我们要记住,所有函数的默认原型都是object的实例,因此默认原型都会包含一个内部指针,指向object.prototype,这也正是所有自定义类型都会继承tostring()等默认方法的原因。

    继承中使用引用类型变量的问题

    function Person() {
    
                    this.age = 12;
    
                    this.color = ["red", "black"];
    
                }
    
                Person.prototype.Say = function () {
    
                    console.log("hello");
    
                }
    
                function Students() {
    
                    this.name = "aa";
    
                }
    
                Students.prototype.Learn = function () {
    
                    console.log("study");
    
                }
    
                Students.prototype = new Person();
    
     
    
                var student = new Students();
    
                student.color[0] = "white";
    
                student.age = 55;
    
                console.log(student.color[0]); //white
    
                console.log(student.age); //55
    
                var student1 = new Students();
    
                console.log(student1.color[0]);////white
    
                console.log(student1.age); //12

    可以看到,上面使用值类型定义的变量没有共享,而引用类型的变量产生了共享,某个实例在修改引用类型的变量时,会直接影响所有实例的值,因这显然是不科学的

    解决方法:

    function Person() {
    
                    this.age = 12;
    
                    this.color = ["red", "black"];
    
                }
    
                Person.prototype.Say = function () {
    
                    console.log("hello");
    
                }
    
                function Students() {
    
                    Person.call(this);
    
                    this.name = "aa";
    
                }
    
                Students.prototype.Learn = function () {
    
                    console.log("study");
    
                }
    
                Students.prototype = new Person();
    
     
    
                var student = new Students();
    
                student.color[0] = "white";
    
                student.age = 55;
    
                console.log(student.color[0]); //white
    
                console.log(student.age); //55
    
                var student1 = new Students();
    
                console.log(student1.color[0]);////red
    
                console.log(student1.age); //12

    解决方法是,在子类型构造函数的内部调用超类型构造函数,这样使用apply和call方法,可以在以后新创建的对象上执行构造函数。

    最理想的继承方法:

    function Person() {
    
                    this.age = 12;
    
                    this.color = ["red", "black"];
    
                }
    
                Person.prototype.Say = function () {
    
                    console.log("hello");
    
                }
    
                function Students() {
    
                    Person.call(this);
    
                    this.name = "aa";
    
                }
    
                Students.prototype.Learn = function () {
    
                    console.log("study");
    
                }
    
                function inheritPrototype(subType, superType) {
    
                    var prototype = Object.create(superType.prototype);
    
                    prototype.constructor = subType;
    
                    subType.prototype = prototype;
    
                }
    
                inheritPrototype(Students, Person);
    
                var student = new Students();
    
                var student1 = new Students();
    
                student.color[0] = "white";
    
                console.log(student.color[0]);
    
                          console.log(student1.color[0]);

    这中法只调用了一次父类的构造函数,并且避免子类的prototype上创建不必要的属性,还能保持原型链的不变,所以这是最理想的方式。

     

     

     

     

  • 相关阅读:
    学习Spring Boot:(八)Mybatis使用分页插件PageHelper
    学习Spring Boot:(七)集成Mybatis
    学习Spring Boot:(六) 集成Swagger2
    学习Spring Boot:(五)使用 devtools热部署
    学习Spring Boot:(四)应用日志
    学习Spring Boot:(三)配置文件
    学习Spring Boot:(二)启动原理
    学习Spring Boot:(一)入门
    Java8 新特性Stream 的学习和使用方法
    简易promise的实现(二)
  • 原文地址:https://www.cnblogs.com/y8932809/p/5395193.html
Copyright © 2011-2022 走看看