• JavaScript中的原型与原型链


    原型

    原型就是每一个函数天生就可以调用的属性,这些属性每一个对象都有,对象中有 constructor 属性表示构造函数本身。

    1. 作用:实例共享属性和方法;
    2. 特点:每一个实例化对象天生就可以访问类原型中的所有内容;

    就比如,所有的对象都有 toString 和 valueOf 属性,我们就不需要给每个对象一个 toString 和 valueOf。因为 JavaScript 的做法就是把 toString 和valueOf 属性放在一个对象里(暂且叫做公用属性组成的对象),然后让每一个对象的 __proto__ 存储这个「公用属性组成的对象」的地址。

    我们先来看下面这段代码:

    let obj1 = new Object()
    let obj2 = new Object()
    console.log(obj1 === obj2)    // false
    console.log(obj1.toString === obj2.toString)    // true
    

    在上面的代码中 obj1 和 obj2 是不严格相等的,因为这两个空对象的地址不同,但是他们转为 toString 之后是相等的。虽然我们并没有给这两个空对象添加 toString 属性,但是它们自带了 toString 属性,其实这里的 toString 属性就是一个原型。


    原型链

    当对象使用属性的时候,首先在自身进行查找,如果有就直接使用,如果没有就沿着 __proto__ 这条链往下查找,直到找到 Object 原型位置,有就返回相应的值,没有就返回 underfined。

    var n = new Number()
    console.log(n.__proto__ === Number.prototype)    // true
    console.log(n.__proto__.__proto__ === Object.prototype)    // true
    
    console.log(Object.prototype.__proto__ === null)    // true
    
    var 对象 = new 函数()
    
    // __proto__ 是对象的属性,prototype 是函数的属性
    对象.__proto__ === 函数.prototype
    
    // 函数的 prototype 是对象,这个对象对应的就是函数 Object
    函数.prototype.__proto__ === Object.prototype
    
    // 由于函数本身即是函数(最优先被视为函数),也是对象,而函数的构造函数是 Function
    函数.__proto__ === Function.prototype
    
    // Function 即是对象,也是函数,但他优先是个函数
    Function.__proto__ === Function.prototype
    
    // Function.prototype 也是对象,是普通的对象,所以其对应的函数是Object
    Funciton.prototype.__proto__=== Object.prototype
    

    所有函数都是由 Function 构造出来的,因此:

    // Object 是函数,是 Function 的实例
    console.log(Object.__proto__ === Function.prototype)    // true
    

    最后我们再来看看这张图:

    原型与原型链


    下面我们来使用下 class:

    class People {
      constructor(id, name) {
        this.id = id
        this.name = name
      }
      sayHi() {
        console.log("id 是 " + this.id + ",名字是 " + this.name)
      }
    }
    
    class Student extends People {
      constructor(id, name, age) {
        super(id, name)
        this.age = age
      }
      sayHi() {
        console.log("id 是 " + this.id + ",名字是 " + this.name + ",年龄是 " + this.age)
      }
    }
    
    let lq = new People(0, 'zww')
    console.log(lq)    // People {id: 0, name: "zww"}
    lq.sayHi()    // id 是 0,名字是 zww
    
    let zww = new Student(0, 'zww', 18)
    console.log(zww)    // Student {id: 0, name: "zww", age: 18}
    zww.sayHi()    // id 是 0,名字是 zww,年龄是 18
    
    // class 实际上是函数
    console.log(typeof People)    // function
    console.log(typeof Student)    // function
    
    console.log(zww.__proto__ === Student.prototype)    // true
    console.log(zww.__proto__.__proto__ === People.prototype)    // true
    
    console.log(People.__proto__ === Function.prototype)    // true
    console.log(People.__proto__ === Object.__proto__)    // true
    console.log(People.__proto__.__proto__ === Object.prototype)    // true
    
    1. 每个 class 都有显式原型 prototype;
    2. 每个实例都有隐式原型 __proto__;
    3. 实例的 __proto__ 指向对应 class 的 prototype;

  • 相关阅读:
    设计算法,根据输入的学生人数和成绩建立一个单链表,并累计成绩不及格的人数。
    git的使用,看这一篇就够啦!(包含github、码云、gitlab)
    设单链表的数据为互不相等的整数,建立一个单链表,并设计一个算法,找出单链表中元素值最大 的结点。
    “Failed to get convolution algorithm. This is probably because cuDNN failed to initialize”错误的解决办法
    回文指的是一个字符串从前面读和从后面读都一 样,编写一个算法判断一个字符串是否为回文。
    怎么搭建一个5T的私有云盘
    基于大数据分析与可视化的疫情信息发布系统
    如何给oneindex网盘增加评论、密码查看、read me,头提示功能。
    解析原理:微信自动查找优惠券做返利机器人是怎么实现的
    【Swift】接入阿里云一键登录(源码,可以直接贴走)
  • 原文地址:https://www.cnblogs.com/LqZww/p/13932602.html
Copyright © 2020-2023  润新知