问答一下,轻松解决,电脑应用解决专家!
主板显卡CPU内存显示器
硬盘维修显卡维修显示器维修
注册表系统命令DOS命令Win8
存储光存储鼠标键盘
内存维修打印机维修
WinXPWin7Win10/Win11
硬件综合机箱电源散热器手机数码
主板维修CPU维修键盘鼠标维修
Word教程Excel教程PowerPointWPS
网络工具系统工具图像工具
数据库javascriptLinux系统
PHP教程CSS教程XML教程

谈一谈javascript原型链机制

更新时间:2021-08-08 14:15 作者:北极光之夜。点击:

一.速识概念:

 原型链可谓是面试频考,所以今天带大家快速了解下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);

在这里插入图片描述

四. 结尾:

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

顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
你可能感兴趣的内容