最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 面不面试的,你都得懂原型和原型链

    正文概述 掘金(尼克陈)   2021-03-01   754

    前言

    不要为了面试而去背题,匆匆忙忙的,不仅学不进去,背完了几天后马上会忘记。

    面不面试的,你都得懂原型和原型链

    你可能会说,“没办法,这不是为了能找份工作嘛!”。我想说的是,“那你没开始找工作的时候,咋不好好学习呢。”

    好了,上述扯的这些,意思就是让大家不要做收藏家,不要把好文收藏了,就放在收藏夹里吃灰!

    下面为大家简单阐述我对原型和原型链的理解,若是觉得有说的不对的地方,还望直接把页面关闭了,别在我这篇文章上继续浪费时间。(逃)

    面不面试的,你都得懂原型和原型链

    四个规则

    我们先来了解下面引用类型的四个规则:

    1、引用类型,都具有对象特性,即可自由扩展属性。 2、引用类型,都有一个隐式原型 __proto__ 属性,属性值是一个普通的对象。 3、引用类型,隐式原型 __proto__ 的属性值指向它的构造函数的显式原型 prototype 属性值。 4、当你试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么它会去它的隐式原型 __proto__(也就是它的构造函数的显式原型 prototype)中寻找。

    下面我们逐一验证上面几个规则,就会慢慢地理解原型和原型链。

    规则一

    引用类型,都具有对象特性,即可自由扩展属性:

    const obj = {}
    const arr = []
    const fn = function () {}
    
    obj.a = 1
    arr.a = 2
    fn.a = 1
    
    console.log(obj.a) // 1
    console.log(arr.a) // 1
    console.log(fn.a) // 1
    

    规则二

    引用类型,都有一个隐式原型 __proto__ 属性,属性值是一个普通的对象:

    const obj = {};
    const arr = [];
    const fn = function() {}
    
    console.log('obj.__proto__', obj.__proto__);
    console.log('arr.__proto__', arr.__proto__);
    console.log('fn.__proto__', fn.__proto__);
    

    面不面试的,你都得懂原型和原型链

    规则三

    引用类型,隐式原型 __proto__ 的属性值指向它的构造函数的显式原型 prototype 属性值:

    const obj = {};
    const arr = [];
    const fn = function() {}
    
    obj.__proto__ == Object.prototype // true
    arr.__proto__ === Array.prototype // true
    fn.__proto__ == Function.prototype // true
    

    规则四

    当你试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么它会去它的隐式原型 __proto__(也就是它的构造函数的显式原型 prototype)中寻找:

    const obj = { a:1 }
    obj.toString
    // ƒ toString() { [native code] }
    

    首先, obj 对象并没有 toString 属性,之所以能获取到 toString 属性,是遵循了第四条规则,从它的构造函数 Object 的 prototype 里去获取。

    一个特例

    我试图想推翻上面的规则,看下面这段代码:

    function Person(name) {
      this.name = name
      return this // 其实这行可以不写,默认返回 this 对象
    }
    
    var nick = new Person("nick")
    nick.toString
    // ƒ toString() { [native code] }
    

    按理说, nick 是 Person 构造函数生成的实例,而 Person 的 prototype 并没有 toString 方法,那么为什么, nick 能获取到 toString 方法?

    这里就引出 原型链 的概念了, nick 实例先从自身出发检讨自己,发现并没有 toString 方法。找不到,就往上走,找 Person 构造函数的 prototype 属性,还是没找到。构造函数的 prototype 也是一个对象嘛,那对象的构造函数是 Object ,所以就找到了 Object.prototype 下的 toString 方法。

    面不面试的,你都得懂原型和原型链

    一张图片

    用图片描述原型链:

    面不面试的,你都得懂原型和原型链

    最后一个 null,设计上是为了避免死循环而设置的, Object.prototype 的隐式原型指向 null

    一个方法

    instanceof 运算符用于测试构造函数的 prototype 属性是否出现在对象原型链中的任何位置。 instanceof 的简易手写版,如下所示:

    // 变量R的原型 存在于 变量L的原型链上
    function instance_of (L, R) {    
      // 验证如果为基本数据类型,就直接返回 false
      const baseType = ['string', 'number', 'boolean', 'undefined', 'symbol']
      if(baseType.includes(typeof(L))) { return false }
    
      let RP = R.prototype;  // 取 R 的显示原型
      L = L.__proto__; // 取 L 的隐式原型
      while (true) {
        if (L === null) { // 找到最顶层
          return false;
        }
        if (L === RP) { // 严格相等
          return true;
        }
        L = L.__proto__;  // 没找到继续向上一层原型链查找
      }
    }
    

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

    function Foo(name) {
      this.name = name;
    }
    var f = new Foo('nick')
    
    f instanceof Foo // true
    f instanceof Object // true
    

    上述代码判断流程大致如下:

    1、 f instanceof Foof 的隐式原型 __proto__ 和 Foo.prototype ,是相等的,所以返回 true 。

    2、 f instanceof Objectf 的隐式原型 __proto__ ,和 Object.prototype 不等,所以继续往上走。 f 的隐式原型 __proto__ 指向 Foo.prototype ,所以继续用 Foo.prototype.__proto__ 去对比 Object.prototype ,这会儿就相等了,因为 Foo.prototype 就是一个普通的对象。

    总结

    通过四个特性、一个例子、一张图片、一个方法,大家应该对原型和原型链的关系有了大概的认知。我的认知就是,原型链就是一个过程,原型是原型链这个过程中的一个单位,贯穿整个原型链。就好像你要是看完了不点个赞,我可以顺着网线找到你。


    起源地下载网 » 面不面试的,你都得懂原型和原型链

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元