美文网首页
谈谈 js 原型链

谈谈 js 原型链

作者: 小纪同学_ | 来源:发表于2021-03-23 13:49 被阅读0次

原型链是为了实现继承,也就是说js的继承是基于原型链的。原型-prototype,是一个对象,用于存放共享的属性和方法的。

原型

原型主要有这么几个概念:
__proto__、prototype、constructor

什么是__proto__?
js会为每个对象添加一个属性,这个属性指向另外一个对象的prototype,js可以通过 Object.getPrototypeOf(obj)获取,chrom浏览器实现为__proto__

什么是prototype?
js会为每个函数添加一个prototype属性,表示自己的原型对象。
prototype是个对象。

什么是constructor?
是js创建和初始化对象的方法,如果没有自己指定constructor,则会默认有个空的constructor
原型对象的constructor指向自己的创造者,每个原型对象都有constructor。所有对象都会从它的原型上继承 constructor 属性。

Tips:
1.函数也是对象,所以函数也有 __proto__ 属性。
2.规定 Object.prototype.__proto__ === null。
3.默认情况下,除 Object 函数的 prototype.__proto__ 都是 Object.prototype。
4.除Object函数的__proto__永远指向prototype。

⚠️注意:这里有个特殊的函数: Function,任何函数都是 Function 的实例,包括 Object。所以 Function 可以说是根构造函数。
所以 Object.__proto__ 就是Function.prototype
所以 Function.__proto__ 也是Function.prototype

Object.__proto__和Function.__proto__

以上就是主要知识点,为了理解咱们举个🌰:

创建一个普普通通的函数A

function A(){}

此时 A 里面有prototype,__proto__两个属性。
A同时继承了A.prototype.constructor

A.prototype

A.prototype 就是它的原型对象,里面有什么?
constructor__proto__,为什么会有__proto__?因为prototype也是个对象。
A.prototype.constructor 指向了谁?当然是A,prototype里面的constructor指向它的函数
A.prototype.__proto__ 指向了谁?当然是Object.prototype,因为默认情况下,任何函数的原型属性 __proto__ 都是Object.prototype

A.prototype.constructor
A.prototype.__proto__

A.__proto__

A.__proto__是什么?应该知道它指向一个prototype,那么是谁的prototype?
当然是Function的。因为它也是由Function创建的。__proto__是由浏览器实现的,不是标准写法,Object 提供了获取原型的方法:getPrototypeOf
Object.getPrototypeOf(A)

A.__proto__
Object.getPrototypeOf(A) 获取A的原型

A.constructor

A.constructor,实际是 A.prototype.constructor,指向自己的创造者:Function


A.constructor

原型链

创建一个A的实例:

a = new A();

根据上面讲述,a会有 __proto__constructor两个属性,并且a.__proto__ === A.prototype:
a.constructor为a.__proto__.constructor。

a.__proto__ 和a.constructor
a.__proto__ === A.prototype

如果这个时候A.prototype中如果有属性,或者方法,a都是可以调用的。


image.png
image.png

两个对象通过__proto__连接,就组成了原型链。
可以给对象指定原型(不建议这么做),这里举例仅是为了理解原型链。将A的实例赋值给B的原型,这样可以理解为B继承了A,B创建的实例b也可以调用A原型中的方法了:


image.png

整体结构图如下:


image.png

从上面例子可以看出js创建一个对象(使用new操作符)大致过程:

  1. 创建一个对象
  2. 给它一个原型
  3. 把对象放进constructor加工

创建一个对象:


创建对象
<!-- new 一个 A 对象  -->
function newA(...args) {
  var self = Object.create(A.prototype)
  var res = A.prototype.constructor.call(self, ...args)
  if (typeof res === 'object' && res !== null) {
    return res
  }
  return self
}

应用与总结

像Array中的forEach,find,filter等都是在Array.prototype上,这样的内置对象还有很多。
es6实现了class语法糖,实际还是应用原型链。

// function A(name) {
//   this.name = name;
// }

// A.prototype.run = function() {
//   console.log(`${this.name} running...`);
// };

class A {
  constructor(name) {
    this.name = name;
  }

  run() {
    console.log(`${this.name} running...`);
  }
}

但是不建议修改内置对象的原型,会产生一些副作用,比如:


image.png image.png

相关文章

  • 谈谈 js 原型链

    原型链是为了实现继承,也就是说js的继承是基于原型链的。原型-prototype,是一个对象,用于存放共享的属性和...

  • JS原型理解

    原型链是整个JS面向对象的基础在理解原型链之前先来谈谈JS创建对象的几种方式 可以看到输出了4个对象,a1和a2看...

  • 廖雪峰JS小记

    (function(){})() 原型,原型链 浅谈Js原型的理解JS 原型与原型链终极详解 对象 对象:一种无序...

  • 谈谈js原型和原型链

    谈到原型和原型链,相信很多人都会想到js类与继承,但由于js是基于对象的语言,并不是面向对象的,所以它本身并没有类...

  • 1.原型和原型链-作用域和作用域链

    一、请谈谈原型和原型链 原型js中每个函数都有一个属性,prototype,这个属性的属性值是一个对象,这个对象被...

  • JS的__proto__和prototype

    最近在回顾JS的原型和原型链的知识,熟悉JS的同学都知道JS的继承是靠原型链实现的,那跟原型链相关的属性__pro...

  • Javascript(三)之原型继承理解

    进阶路线 3 原型继承 3.1 优秀文章 最详尽的 JS 原型与原型链终极详解 一 最详尽的 JS 原型与原型链终...

  • 从实现角度分析js原型链

    从实现角度分析js原型链 欢迎来我的博客阅读:《从实现角度分析js原型链》 网上介绍原型链的优质文章已经有很多了,...

  • JS原型链

    1什么是JS原型链? 通过__proto__属性将对象与原型对象进行连接. 1.1 JS原型链的作用? 组成的一个...

  • 关于JS中的原型和原型链

    目录 关于js 对象和原型 原型链 基于原型链的继承 参考资料ECMAScript 6 入门JavaScript原...

网友评论

      本文标题:谈谈 js 原型链

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