• Js原型及原型链


    1.原型的概念离不开构造函数,首先需要了解构造函数。
    1.1. 构造函数分为实例成员和静态成员
    实例成员:在构造函数内部,通过this添加的成员,其只能通过实例化的对象来访问。
    静态成员:在构造函数本身上添加的成员,只能通过构造函数访问。

    function emp(name,age){
          //实例成员
          this.name = name;
          this.age = age;
    }
    //静态成员
    emp.sex = '男';
    
    let eOne = new emp('老董',30);
    console.log(eOne);      // emp{name: "老董", age: 30}
    console.log(eOne.sex);  // undefined     实例无法访问sex属性
    
    console.log(emp.name); //emp   通过构造函数无法直接访问实例成员
    console.log(emp.sex);  //男    通过构造函数可直接访问静态成员
    

    1.2 通过构造函数创建对象(该过程也叫实例化)

    function Student(name) {
         this.name = name;
     }
     let stu1 = new Student('小王');
     console.log(stu1); //Student{name: "小王"}
    

    此时,Student就是一个新对象

    1.2.1 在new一个新对象的过程中,发生了如下步骤:
    ①创建了一个空的stu1{}对象
    ②为stu1准备原型连接接stu1.proto = Student.prototype
    ③重新绑定this,使构造函数的this指向新对象Student.call(this)
    ④为新对象赋值,stu1.name
    ⑤返回this return this,此时的新对象就拥有了构造函数的方法和属性了

    1.2.2 区分实例的方法是否共享
    结论:在构造函数直接定义为不共享的,通过原型链添加的方法为共享方法。
    构造函数直接定义(非共享):

    function Student() {
            this.sing = function () {
                console.log('我爱唱歌');
            }
        }
        let stu1 = new Student();
        let stu2 = new Student();
        stu1.sing();//我爱唱歌
        stu2.sing();//我爱唱歌
        console.log(stu1.sing === stu2.sing);//false
    

    很明显,stu1 和 stu2 指向的不是一个地方。所以 在构造函数上通过this来添加方法的方式来生成实例,每次生成实例,都是新开辟一个内存空间存方法。这样会导致内存的极大浪费,从而影响性能。

    通过原型添加方法(共享):

    function Student(name) {
            this.name = name;
        }
        Student.prototype.sing = function () {
            console.log('我爱唱歌', this.name);
        };
        let stu1 = new Student('小汪');
        let stu2 = new Student('小徐');
        stu1.sing();//我爱唱歌 小汪
        stu2.sing();//我爱唱歌 小徐
        console.log(stu1.sing === stu2.sing);//true
    

    2.原型
    2.1 经过以上例子,Student.prototype 其实就是原型,本质上其为对象,所以叫原型对象。
    2.2 原型的作用就是用来共享方法(通过Student.prototype.method共享方法,而不会开辟空间储存方法)
    2.3 原型中的this指向的就是实例

    3.原型链
    3.1 原型 与 原型 层层相链接的过程即为原型链
    3.2 原型链的应用:对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在(每个对象都有__proto__原型的存在)

    function Student(name,age) {
        this.name = name;
        this.age = age;
    }
    Student.prototype.eat = function(){
        console.log('吃饭',this.name);
    };
    let obj = new Student('自gay',12);
    console.log(obj.__proto__ === Student.prototype);//true
    

    3.3 原型查找方式
    function Student(name) {
    this.name = name;

        (1)首先看obj对象身上是否有eat方法,如果有,则执行对象身上的方法
        this.eat= function () {
            console.log(this.name + '1');
        }
    }
    
    (2)如果没有eat方法,就去构造函数原型对象prototype身上去查找eat这个方法。
    Student.prototype.eat= function () {
        console.log(this.name + '2');
    };
    
    (3)如果再没有eat方法,就去Object原型对象prototype身上去查找eat这个方法。
    Object.prototype.eat= function () {
        console.log(this.name + '3');
    };
    (4)如果再没有,则会报错。
    let obj = new Student('小张');
    obj.eat();
    

    3.4 原型链图

  • 相关阅读:
    eclipse导入github项目
    深入理解BFC和Margin Collapse
    前端开发必备!Emmet使用手册
    Backbone.js的技巧和模式
    智能选择器和语义化的CSS
    IE常见BUG总结(持续更新)
    表格元素的完全指南(译)
    display:inline-block;在各浏览器下的问题和终极兼容办法
    float的深入剖析
    javascript正则表达式小技巧
  • 原文地址:https://www.cnblogs.com/bemad/p/13070983.html
Copyright © 2020-2023  润新知