• JS 原型 & 继承


    理解原型链

    先看看http://www.ituring.com.cn/article/56184和http://www.cavabiao.com/prototype-and-inherit-of-javascript/

    首先需要知道new的时候都发生了什么
    总的来说就是new得到的对象的_proto_指向F的prototype
    比如 new F(); 下面是turing社区的讲解
    new 运算符接受一个类(函数)F 及其参数new F(arguments...)
    这一过程分为三步:
    创建类的实例。这步是把一个空的对象的 _proto_ 属性设置为 F.prototype 。
    初始化实例。函数 F 被传入参数并调用,关键字 this 被设定为该实例。
    返回实例。

    function New(f) {
      var n = {
        '__proto__': f.prototype
      }; /*第一步*/
      return function() {
        f.apply(n, arguments); /*第二步*/
        return n; /*第三步*/
      };
    }

    原型式继承

    下面是最简单的使用原型的例子

    function Point(x, y) {
      this.x = x;
      this.y = y;
    }
    Point.prototype = {
      print: function() {
        console.log(this.x, this.y);
      }
    };
    
    var p = new Point(10, 20);
    p.print(); // 10 20

    原型继承 简单来说就是修改该类(function)的prototype属性值 指向另一个对象

    不过我们可以定义一个通用的方式来完成继承 这是 Douglas Crockford 提出的一种方案
    定义如下函数

    function object(o) {
      function F() {};
      F.prototype = o;
      return new F();
    }

    实际上这个函数就是ECMA5中定义的Object.create函

    一个使用原型方式继承的例子

    function object(o) {
      function F() {};
      F.prototype = o;
      return new F();
    }
    
    var person = {
      name: 'nico',
      friends: ['aaa', 'bbb', 'ccc']
    }
    
    var anotherPerson = object(person);
    var yetAntherPerson = object(person);
    anotherPerson.name = 'greg';
    
    console.log(anotherPerson.name); //gerg//因为上一句为antherPerson增加一个name属性并赋值//原型name还是nico
    console.log(yetAntherPerson.name); //nico
    
    anotherPerson.friends.push('ddd'); //因为我这里是对friends做修改 所以不会为anotherPerson创建新的属性
    // 查找anotherPerson下的friends属性 在其原型中找到了 所以这里的修改是原型中friends
    
    console.log(anotherPerson.friends); //["aaa", "bbb", "ccc", "ddd"] 
    console.log(yetAntherPerson.friends); //["aaa", "bbb", "ccc", "ddd"]
    
    anotherPerson.friends = ['ano1', 'ano2']; //虽然也是friends 但是这个friends后面紧接着是一个赋值符号 //所以这里是为anotherPerson创建一个新的属性
    console.log(anotherPerson.friends); //["ano1","ano2"]
    console.log(yetAntherPerson); //["aaa", "bbb", "ccc", "ddd"]

    关于 实例 类 原型的关系 看这个图http://www.ituring.com.cn/download/01Yi3zzVQhOo
    cf1 cf2... 都是CF类的实例 cf1 cf2...都拥有一个_proto_ 属性 指向其类的原型 所以cf1改的是原型的属性 其他的实例cf2 cf3去引用原型的变量话肯定是cf1修改过后

    这样感觉很不好 对不对 我希望我继承的对象的属性都是独立的 不会因为其它对象的改变而变化

    下面就得说组合式继承
    组合式继承使用原型链的方式对原型的属性和方法做继承 通过借用构造函数的方式实现实例属性的继承

    nction SuperType(name) {
        this.name = name;
        this.colors = ['red'];
    }
    
    SuperType.prototype = {
        constructor: SuperType, // 我这里是对整个prototype做重写  所以千万不要忘了constructor属性
        sayName: function() {
            console.log(this.name);
        }
    }
    // 上面可以简写为  //这样就不用手动指定constuctor的值
    SuperType.prototype.sayName = function() {
        console.log(this.name);
    }
    
    
    function SubType(name, age) {
        SuperType.call(this, name); //继承属性//调用了SuberType这个构造函数 //相当于这里写上了this.name=name;this.colors=xxx
        this.age = age;
    }
    
    SubType.prototype = new SuperType(); //注意不要写为SubType.prototype=SuperType.prototype 这样的话constructor指向就不对了
    SubType.prototype.constructor = SubType;
    SubType.prototype.sayAge = function() { //为原型添加函数  这样一来原型就有sayName sayAge两个方法了
        console.log(age);
    }
    
    
    console.log(SuperType.prototype);
    console.log(SubType.prototype);
    var superIns = new SuperType('super');
    var subIns = new SubType('sub', 23);
    console.log(superIns);
    console.log(subIns);

     

  • 相关阅读:
    BNU校赛
    Latest Common Ancestor
    Codeforces Round #482 (Div. 2)
    Persistent Line Segment Tree
    2018HNCCPC(Onsite)
    2018HNCCPC
    2017 ACM Jordanian Collegiate Programming Contest
    Codeforces Round #480 (Div. 2)
    负载均衡SLB
    windows下的端口监听、程序端口查找命令
  • 原文地址:https://www.cnblogs.com/cart55free99/p/3769062.html
Copyright © 2020-2023  润新知