JavaScript基础篇-原型与原型链

261 阅读3分钟

前言

首先对象都有原型和原型链,通过原型链我们可以找到对象的"继承",可以通过原型链找到父类以及顶级 Object 的参数和方法,并且使用它们。在对象中又包含一个隐式原型(proto)和一个显式原型(prototype),构造函数通过 prototype 可以找到它们的原型,而实例函数可以通过 proto 找到它们的原型。

继承属性

JavaScript 对象是动态的属性“包”(指其自己的属性)。JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

创建对象

创建对象一般有三种方法,字面量、构造函数、Object.create

第一种:字面量 var o1 = { name: 'o1' } var o2 = new Object({ name: 'o2' })

第二种:构造函数 var M = function(name) { this.name = name } var o3 = new M('o3')

第三种:Object.create var P = { name: 'p' } var o4 = Object.create(P)

构造函数和普通函数的区别

如果一个函数被 new 实例后,那么这个函数就是构造函数 一般构造函数的函数名首字母都要大写 构造函数中都会有自己的 this,而普通函数中的 this 是指向 window 的

构造函数、实例函数、原型对象、原型链

构造函数:

创建一个函数并且该函数被 new 实例化过

实例函数:

通过 new 实例化一个函数

原型对象:

构造函数的原型,可以在上面新增一些属性和方法

原型链:

实例可以通过 proto 拿到构造函数的原型

它们之间的关联

这里的核心人物就是构造函数,它可以使用 prototype 获得它的原型,而原型可以通过 constructor 指回构造函数,也可以使用 new 创建一个实例,实例可以通过 proto 获取构造函数的原型,而该构造函数的原型对象你可以看作是父类函数的一个 实例函数 关系如下图:

instanceof的原理

instanceof 用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上,我们知道 typeof 是判断数据类型的,但是它判断不了 Object 类型的继承,所以我们可以使用 instanceof 进行判断,判断某个实例对象是否在对象的原型链上。 但是 instanceof 也有不严谨的地方,它无法分辨判断出来的结果是否是它本身的构造函数,所以想要更精准的判断可以使用 实例对象.proto.constructor === 构造函数

new 运算符

一个新对象被创建,它继承自 foo.prototype 构造函数 foo 被执行:执行的时候,相应的传参会被传入,同时上下文(this)会被指定为这个新实例。new foo 等同于 new foo(),只能用在不传递任何参数的情况 如果构造函数返回了一个"对象",那么这个对象会取代整个 new 出来的结果,如果构造函数没有返回对象,那么 new 出来的结果为步骤1创建的对象