javascript 中的原型链
javascript
有两大链条,一条是作用域链
,一条是原型链
今天我们来开始撸一撸javascript
的这条原型链
(想和Up主聊聊作用域链的Baby,可以关注来一波哈, —————— 爱你的小Up)
OK、正文开始~~
概念解释
javascript是一种面向对象的、解释型弱语言,那下面我们先弄清楚这几个概念
- 函数(function)
- 函数对象(function object)
- 本地对象(native object)
- 内置对象(build-in object)
- 宿主对象(host object)
函数
前者为函数声明,后者为函数字面量,typeof person/person1的结果都是 function
函数对象
函数就是对象,代表函数的对象就是函数对象
上面,我们所建立的对象,就是函数对象
本地对象
ECMA-262 把本地对象(native object)定义为“独立于宿主环境的 ECMAScript 实现提供的对象”。简单来说,本地对象就是 ECMA-262 定义的类(引用类型)。它们包括: Object,Function,Array,String,Boolean,Number Date,RegExp,Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError.
我们不能被他们起的名字是本地对象,就把他们理解成对象(虽然是事实上,它就是一个对象,因为JS中万物皆为对象),通过typeof 返回的结果都是function
也就是说其实这些本地对象(类)是通过function
建立起来的
可以看出Object原本就是一个函数,通过new Object()之后实例化后,创建对象。
内置对象
ECMA-262 把内置对象(built-in object)定义为“由 ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript 程序开始执行时出现”。这意味着开发者不必明确实例化内置对象,它已被实例化了。ECMA-262 只定义了两个内置对象,即 Global 和 Math (它们也是本地对象,根据定义,每个内置对象都是本地对象)。
理清楚了这几个概念,有助于理解我们下面要讲述的原型和原型链。
什么是原型
想知道原型,我们先来搞明白三个关键字,哦不,是关键词!
- __proto__
- prototype
- constructor
__proto__、 prototype
任何对象都有一个原型对象,这个原型对象由对象的内置属性__proto__
指向它的构造函数的prototype
指向的对象,即任何对象都是由一个构造函数创建的,但是不是每一个对象都有prototype
,只有方法才有prototype
constructor
用function
声明的都是函数,而如果直接调用的话,那么Person()
就是一个普通函数,只有用函数new产生对象时,这个函数才是new出来对象的构造函数。(看完这几个关键词有点晕了?是不是很绕?那先上个图看看 -_-!)
创建对象的过程
知道什么是原型了,那么我们来聊一聊创建对象的过程
声明构造方法(类)
为啥在构造方法后面加个类呢,是因为类即class也可以创建对象
ES5 => 构造方法 ES6 => 类class
Tip:通常构造函数和类的命名使用大驼峰
new一个对象
没有对象?不怕!new一个不就完事了,让我们来看一下他们之间的关系
我们可以的发现,new
出来的对象,它的constructor
指向了Person
。
即new
一个对象,它的__proto__
属性指向了方法的prototype
属性,并且constructor
指向了prototype
的constructor
属性。
new到底干了什么
- 创建一个空对象
- 设置这个新的对象的内部、可访问性和
[[prototype]]
属性为构造函数(指prototype.construtor
所指向的构造函数)中设置的; - 执行构造函数,当
this
关键字被提及的时候,使用新创建的对象的属性; 返回新创建的对象(除非构造方法中返回的是‘无原型’)。 - 在创建新对象成功之后,如果调用一个新对象没有的属性的时候,JavaScript 会延原型链向止逐层查找对应的内容。这类似于传统的‘类继承’。
Tip: 在第二点中所说的有关[[prototype]]
属性,只有在一个对象被创建的时候起作用,比如使用new
关键字、使用 Object.create
、基于字面意义的(函数默认为 Function.prototype
,数字默认为 Number.prototype
等)。它只能被Object.getPrototypeOf(someObject)
所读取。没有其他任何方式来设置或读取这个值。送上权威文档的飞机票
原型链
上面讲了那么多就是为下面做铺垫,嘻嘻
什么是原型链?
原型链的核心就是依赖对象的__proto__
的指向,当自身不存在的属性时,就一层层的扒出创建对象的构造函数,直至到Object
时,就没有__proto__
指向了。
原型链的简单实践
多级原型链接成为了原型链
原型链的作用
- 实例对象可以使用原型链上对象的方法或者属性
- 查找顺序:从自身往上查找(先到先得)
重写原型链上的方法
原型链图解
这是小编在网上找的图,感觉挺不错的,就推荐给大家
结束语
相信看完这篇文章,你对javascript原型链有了新的理解和认识