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上创建不必要的属性,还能保持原型链的不变,所以这是最理想的方式。

     

     

     

     

  • 相关阅读:
    win2003系统网络安装——基于linux+pxe+dhcp+tftp+samba+ris
    Linux系统网络安装——基于pxe+dhcp+nfs+tftp+kickstart
    写在前面
    windows下使用批处理设置环境变量
    使用广告终结者屏蔽页面的任意部分
    window7 输入什么命令可以快速打开服务管理?? 虚拟机设置了NAT网络连接方式,还是无法上网?
    [转]PHP100视频教程(2012-2013版)下载地址及密码
    窗口对象的方法 prompt() 用来输入数据
    HTML5 canvas标签绘制正三角形 鼠标按下点为中间点,鼠标抬起点为其中一个顶点
    javascript弹出框打印某个数值时,弹出NaN?(not a number)
  • 原文地址:https://www.cnblogs.com/y8932809/p/5395193.html
Copyright © 2011-2022 走看看