美文网首页
原型与原型链

原型与原型链

作者: 写代码的海怪 | 来源:发表于2018-11-05 16:36 被阅读6次

    原型的由来

    考虑如下代码

    var s = '1'
    var n = 1
    var obj = {}
    
    s.toString()
    n.toString()
    obj.toString()
    

    直观上,我们很容易觉得s, n, obj都应该共享toString()函数,但是如果有很多个变量呢?那不是要每个变量都对应一个toString(),这也太麻烦了。所以JS就提出了不如我们将一些共有的变量或者函数放在一起,干脆就用一个对象存起来好了。

    但是是放在一起也有问题,字符串不能有parseInt()的函数,而数字不应该有endWith()函数呀,所以对这个共同的对象进行一下分类变成了我们所知道的Number, String, Boolean, Object等。这个共同的对象就是我们所说的原型

    原型链

    好了,现在我们有一个共同的地方可以放东西了,那怎么取这些东西呢?难道我们每个变量都要存对应的方法名字?不,这里我们在每个对象里存一个指向原型的地址就好了,当我们访问一些共有的属性时,用这个引用不好了了么?这个引用就是我们所说的__proto__

    // 访问对应的toString方法
    var num = new Number(1)
    num.toFixed()
    
    ===
    // 等价于
    
    num.toFixed()
    

    那么对于toString()方法怎么使用呢?还记得我们之前说的要分类么?而toString()又是一个Number和String共有的属性,所以这就是原型链的由来

    var num = new Number(1)
    
    num.toString()
    
    // 等价于
    num.__proto__(Number.prototype找不到,那就去更加共有的地方去找吧).__proto__(Object.prototype,在这就定义了toString()方法,就用这个了)
    

    对于别的共有函数访问也是一样的,慢慢地,我们就发现这其实是一棵大树

              Object
         /      |       \
    Number    String   Boolean ...
    

    当当前对象找不到某个属性值或者函数时,就从__proto__指向的对象去找,找不到就继续找__proto__里的__proto__,直到找不到为止,就像我们学算法的DFS一样。

    关键的公式

    说了一堆有点晕,其实很容易理解

    对象.__proto__ === 创造者.prototype
    
    =>
    // Number() 创造了数字
    num.__proto__ === Number.prototype // true
    // Boolean() 创造了布尔
    bool__proto__ === Boolean.prototype // true
    // String() 创造了字符串
    str__proto__ === String.prototype // true
    // Object() 创造了对象
    obj__proto__ === Object.prototype // true
    

    注意:函数有奇怪的地方

    Function = {
        __proto__: Function 共用的属性 -> prototype
        prototype: Function 共用的属性 -> __proto__
    }
    

    注意:Number, String, Object 是构造函数,他们所指向的原型是Function.prototype,因为是由Function来构造他们的

    // 构造Object的是一个构造函数,所以是Function.prototype
    Object.__proto__ === Function.prototype // true
    // 和下面的不一样,下面的是由Object构造出来的
    obj.__proto__ === Object.prototype // true
    
    // 因为Object已经是有最高级的存放共有属性的地方了,再往上就没东西找了
    Object.prototype.__proto__ === null
    

    相关文章

      网友评论

          本文标题:原型与原型链

          本文链接:https://www.haomeiwen.com/subject/qrvsxqtx.html