面试官:谈一谈js原型链机制? 我:告辞!

Posted 北极光之夜。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试官:谈一谈js原型链机制? 我:告辞!相关的知识,希望对你有一定的参考价值。

一.速识概念:

 原型链可谓是面试频考,所以今天带大家快速了解下javascript的原型链机制🚀。说之前,先明确下面基本的概念(名称与从属关系),这是很重要的:

名称从属关系
prototype通常我们称之为原型,它是函数的一个属性,它是一个对象。
_ _ proto_ _相当于一个连接点,它是对象的一个属性,它也是一个对象。

二. 原型链机制(建议跟着步骤敲代码):

  其次,我们要知道的第一个点是,对象的 __ proto __ 保存着该对象构造函数的prototype,这是什么意思?莫急,看下面这个例子你就懂了。

1.首先定义一个构造函数:

 function Test(){}

2.打印看它这个函数有没有 prototype属性:

 console.log(Test.prototype);

3.确实有,看得出是一个对象:

4.new一个Test函数,将得到一个对象实例:

const test = new Test();

5.打印看这个对象有没有 __ proto__ 这个属性:

   console.log(test.__proto__);

6.确实有,可以看到也是一个对象:

7.不知道你们发现没有,上面两次打印输出的东西是一样的,现在回到我刚开始提到的第一个知识点,对象的 __ proto __ 保存着该对象构造函数的prototype,判断看是不是真的:

console.log(Test.prototype === test.__proto__);

8.看结果,他们两个果然是相等的,那现在明确了对象的 __ proto __ 保存着该对象构造函数的prototype:


9.既然对象里会有 __ proto __属性,而prototype也是一个对象,理所应当它也应该有 __ proto __属性,输出看看:

 console.log(Test.prototype.__proto__);

10.确实存在着,发现还是一个对象:

11. 我们知道我们自己定义的对象其实都是 new Object 来的,输出Object它的prototype看看:

console.log(Object.prototype);

12.我们发现,它和Test.prototype.__proto__好像是一样的:

13.判断一下,发现返回的是ture,证明他们果然是一样的:

 console.log(Object.prototype === Test.prototype.__proto__);


14. 那现在我们知道了以下:test里有一个__proto__属性和Test的prototype属性相等,Test的prototype属性里的__proto__和Object.prototype相等,那Object里的prototype属性还有__proto__属性吗?如下所示,返回null,确实是没有了,Object就是走到头了。

  console.log(Object.prototype.__proto__);


 按照上面结果,我们可以得到下面结论:原型链就是一个以对象为基准,这个对象通过__proto__这个属性为连接点找到了它的构造函数的prototype,而这个prototype也是一个对象,它也有__proto__属性,它也以这个为连接点找到了Obje.prototype,而Object的prototype不存在__proto__属性了,所以链条到此为止。
 当然上面只是最简单的原型链,很多情况会复杂许多,只需要知道一个对象可以通过__proto__属性为连接点,一直连连连,一直连到Obje.prototype为止。

15.现在我给构造函数定义一个a,输出test发现是存在的:

   function Test() {
          this.a = 1;
      }
   const test = new Test();
   console.log(test);


16.现在我通过Test.prototype属性里定义一个b,输出test发现b也是存在的,不过它存在test的__proto__里:

   function Test() {
        this.a = 1;
      }
      Test.prototype.b = 2;
      const test = new Test();
      console.log(test);


17.现在我通过Object.prototype属性里定义一个c,输出test发现c竟然也是存在的,不过它存在test的__proto__里的__proto__里,相当于存在Test的prototype属性里的__proto__里,通过前面我们也证明了它确实是等于Object.prototype:

function Test() {
    this.a = 1;
  }
  Test.prototype.b = 2;
  Object.prototype.c = 3;
  const test = new Test();
  console.log(test);


 明明我不是在test里定义的a,b,c,但是都可以从test得到,其实这就是原型链继承机制。
通过这个对象的__proto__属性为连接点往上找,而这个__ proto __ 保存着该对象构造函数的prototype,这里找到了该对象构造函数prototype,而prototype是对象,同样也存在__proto__属性,继续往上找,一直找到Object的prototype,因为Object的prototype不存在__proto__属性,所以一直到Object.prototype便终止。此时a,b,c都在链条上找到了。

18.比如我在Test里也直接定义了c是666,在Object.prototype也定义了c是3,那 test.c 是多少?会是通过原型链上第一次找到的返回,先找到的是Test里的c,所以返回666:

 function Test() {
        this.a = 1;
        this.c = 666;
      }
      Test.prototype.b = 2;
      Object.prototype.c = 3;
      const test = new Test();
      console.log(test);

三.扩展:

1.首先,我们知道我们定义的Test构造函数其实是这样生成的:

const Test = new  Function();

这样一来,不是会有如下关系么:

Test.__proto__ === Function.prototype

输出发现,真的存在:

 console.log(Test.__proto__ === Function.prototype);


既然如此,那么Function.__proto__往上找的话会是什么,结果是没有了,JavaScript底层给我们规定了如下规则:

Function.__proto__ === Function.prototype

2.如果有一个对象:

const obj = {}

它实际是这样来的:

const obj = new Object()

这样一来,岂不是说 Object 是一个构造函数,是一个函数?Object 是一个函数?试试看:

console.log(typeof Object)


确实类型是函数,这样的话岂不是有:

Object.__proto__ === Function.prototype

输出看看:

console.log(Object.__proto__ === Function.prototype)


确实成立,这样一来,便存在以下关系:

Object.__proto__ === Function.__proto__

3.我们可以通过 hasOwnProperty()方法判断一个对象是否存在有此属性,且该属性不是在原型链上继承的。如下:

  Test.prototype.b = 2;
  Object.prototype.c = 3;
  const test = new Test();
  console.log(test.hasOwnProperty("a"));
  console.log(test.hasOwnProperty("b"));
  console.log(test.hasOwnProperty("c"));


当然相对的,可以用 in 来判断一个对象是否存在有此属性,且该属性可以是在原型链上找到继承的:

  function Test() {
    this.a = 1;
  }
  Test.prototype.b = 2;
  Object.prototype.c = 3;
  const test = new Test();
  console.log("a" in test);
  console.log("b" in test);
  console.log("c" in test);

四. 结尾:

原型链介绍到这里就差不多啦,由于我才疏学浅,所以如果有错误的地方恳请大佬指出~🌈🌈🌈

下次再见啦~


其它文章:
~关注我看更多简单创意特效:
文字烟雾效果 html+css+js
环绕倒影加载特效 html+css
气泡浮动背景特效 html+css
简约时钟特效 html+css+js
赛博朋克风格按钮 html+css
仿网易云官网轮播图 html+css+js
水波加载动画 html+css
导航栏滚动渐变效果 html+css+js
书本翻页 html+css
3D立体相册 html+css
霓虹灯绘画板效果 html+css+js
记一些css属性总结(一)
Sass总结笔记
…等等
进我主页看更多~

以上是关于面试官:谈一谈js原型链机制? 我:告辞!的主要内容,如果未能解决你的问题,请参考以下文章

网易前端面试官,来谈一谈你被拒绝的原因

转载腾讯面试题——谈一谈Binder的原理和实现一次拷贝的流程

谈一谈js的内存分配

为拿下校招,谈一谈我的mysql学习之路

❤️一起谈一谈js中的宏任务和微任务!❤️

谈一谈最近学了一段时间的node.js