zoukankan      html  css  js  c++  java
  • js继承实现

     在js里面,继承总是晦涩难懂的。那让我们一步一步来分析js继承。

    首先,继承的目的。我们可以通过new一个构造器的实例对象,就可以实现调用父类的所有的方法。根本不需要propotype之类的。

    来段代码理解下:

        var Person = function(name, age) {
            this.name = name;
            this.age = age;
            this.sayName = function() {
                console.log(this.name);
            };
        };
        var person1 = new Person("bella", 23);
        console.log(person1);

    这里没有用到prototype,person1对象可以直接调用Person构造器中的属性和方法。

    那我们为什么要用到prototype呢?说明通过new一个实例对象的方法是存在缺陷的 。那我们就来分析下,这个缺陷到底是什么?

      var Person = function(name, age) {
            this.name = name;
            this.age = age;
            this.sayName = function() {
                console.log(this.name);
            };
        };
        var person1 = new Person("bella", 23);
        var person2 = new Person("alex", 2);
        console.log(person1);
        console.log(person2);
        console.log(person1.sayName === person2.sayName);

    我们可以看到person1.sayName 不等于person2.name。意味着person1复制了一份sayName,person2也复制了一份sayName. 这样就比较消耗内存了。

    于是我们想要person1和person2两个调用的时同一个sayName,像引用对象一样,调用同一个引用。

    于是就引出了prototype,__proto__,原型链。如果这些知识不懂,先自行搞懂这些。

    我们打印下person1对象,都有哪些东东?

    可以看到有age,name,sayName除外,还有__proto__隐式原型。

    __proto__里面有constructor 和__proto__.那我们就着重看下这个construtor和__proto__

    每个对象都有个__proto__。__proto__.constructor又指向自己,相当于__proto__.constructor = Person;

    __proto__.__proto__ = Person.prototype

    那如果实现继承需要实现什么?

    一个Parent构造器和一个Child构造器。然后Child继承Person,需要实现什么?

     第一步,肯定需要实现Person构造器里面的。

      .call(this);

     第二步,就是通过原型链的原理实现,继承父类原型上的属性和方法。

           Child子类的prototype 里面有constructor和__proto__属性。

      那么继承原理就是:

      Child.prototype.constructor = Child;

      Child.prototype.__proto__ = Parent.prototype;

      这样Child就可以通过原型链找到Parent原型上的方法了。

    所以原理就是第一步和第二步里面标红的3行代码了。

    实现如下:

        var Parent = function(name, age) {
            this.name = name;
            this.age = age;
            this.sayName = function() {
                console.log(this.name);
            };
        };
        Parent.prototype.sayAge = function() {
            console.log(this.age);
        };
    
        var Child = function(name, age) {
            Parent.call(this, name, age);
        };
    
        Child.prototype.__proto__ = Parent.prototype;
        Child.prototype.constructor = Child;
        var child = new Child("bella", 23);
        console.log(child);

    输出结果:

     但是js里面一般不直接操作__proto__属性,所以有了更优化的方案。

     var Parent = function(name, age) {
            this.name = name;
            this.age = age;
            this.sayName = function() {
                console.log(this.name);
            };
        };
        Parent.prototype.sayAge = function() {
            console.log(this.age);
        };
    
        var Child = function(name, age) {
            Parent.call(this, name, age);
        };
        var Temp = function() {};
        Temp.prototype = Parent.prototype;
        var temp = new Temp();
        temp.constructor = Child;
        Child.prototype = temp;
        // Child.prototype.__proto__ = Parent.prototype;
        // Child.prototype.constructor = Child;
        var child = new Parent("bella", 23);
        console.log(child);

    标红部分就是优化之后的代码。很多看着会一脸懵。为什么这个算是优化的?我怎么看不懂。

    需要看懂这个的,首先需要了解new Temp()这个过程做了什么?

    new做了什么,自行去了解。我把new的过程写下来:

        var temp =new Temp();
       //上面一步相当于下面四步
        var obj={};
        Temp.call(this);
        obj.__proto__ = Temp.prototype;
        var temp = obj;

     这样一来是不是有点明白了。

        var Temp = function() {};
        Temp.prototype = Parent.prototype;
        var temp = new Temp();

    这三步就先相当于是

    Child.prototype.__proto__ = Parent.prototype;



     temp.constructor = Child;
    
    

    这一步相当是

    Child.prototype.constructor = Child;
    现在的temp就包含了需要继承的Parent的__proto__和指向Child的constructor.
    然后再把temp赋值给Child.prototype就实现了继承。


    所以理解完这个之后,继承看起来也没有那个晦涩难懂了。
  • 相关阅读:
    Bootstrap 2.2.2 的新特性
    Apache POI 3.9 发布,性能显著提升
    SQL Relay 0.48 发布,数据库中继器
    ProjectForge 4.2.0 发布,项目管理系统
    红帽企业 Linux 发布 6.4 Beta 版本
    红薯 快速的 MySQL 本地和远程密码破解
    MariaDB 宣布成立基金会
    Percona XtraBackup 2.0.4 发布
    Rocks 6.1 发布,光盘机群解决方案
    精通Servlet研究,HttpServlet的实现追究
  • 原文地址:https://www.cnblogs.com/thonrt/p/5901099.html
Copyright © 2011-2022 走看看