JS-原型链

原型对象

原型对象可以让所有对象实例共享它所包含的属性和方法。

  • 每个构造函数都有一个 prototype 属性,指向它的原型对象;原型对象有一个 constructor 属性,指向该函数
  • 用构造函数创建一个新对象后,即实例。这个实例默认有 __proto__ 属性,指向构造函数的原型对象

需要注意:

  • 函数的 prototype 属性指向函数的原型对象,而不是说 prototype 就是原型对象,prototype 是地址,内存中这个地址的位置上的东西才是原型对象
  • 函数也是对象,所以函数也可以有属性

img

img

![image-20210303192201911](/Users/wei/Library/Application Support/typora-user-images/image-20210303192201911.png)

补充

  1. Prototype 是 构造函数才有,也称为 显式原型
  2. 所有对象都有 _proto_ , 也叫 隐式原型
  3. Object.create(null) 创建对象没有 _proto_
  4. 方法是个特殊的对象,除了有属性 _proto_ ,还有属性 prototype, prototype指向方法的

原型链

当试图访问一个对象的属性时,如果没有在该对象上找到,他还会搜索该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。Object.prototype 是 js 原型链的最顶端,它的 __proto__ 是null(有 __proto__ 属性,但值是 null)

我们可以通过 对象.__proto__ 查看对象的原型

Object

Object 本身是一个函数,由 Function 所创建,所以 Object.__proto__ 的值是 Function.prototype,而 Function.prototype__proto__ 属性是 Object.prototype,里面存在着一些对象的方法和属性,例如最常见的 toString 方法

1
2
Person(对象) -> Function.prototype -> Object.prototype -> null
person(实例) -> Person.prototype -> Object.prototype -> null

Array

Array 也是一个函数对象,它的原型就是 Array.prototype。里面存在着一些数组的方法和属性,例如常见的 push,pop 等方法。

1
[1, 2] -> Array.prototype -> Object.prototype -> null

Function

Function 也是一个函数对象,但它有点特殊,它的原型就是一个 function 空函数。

1
fun -> Function.prototype -> Object.prototype -> null

自定义函数

它的原型就是给它指定的那个东西。如果不指定,那它的原型就是一个Object.prototype。

如何确定原型与实现机制的关系?

isPrototypeOf()

作用:检测一个对象是否存在于另一个对象的原型链上

1
2
3
4
5
6
7
8
9
10
11
12
13
var p = {x:1};//定义一个原型对象
var o = Object.create(p);//使用这个原型创建一个对象
// 通过 Object.create() 创建的对象使用第一个参数作为原型
p.isPrototypeOf(o);//=>true:o继承p
// 对象使用 Object.prototype 作为原型
Object.prototype.isPrototypeOf(p);//=> true p继承自Object.prototype

function Animal(){
    this.species = "动物";
 };
var eh = new Animal();
// 通过new创建的对象使用 构造函数的prototype 属性作为原型
Animal.prototype.isPrototypeOf(eh)//=>true

instanceof

作用:检测原型链的对象是否存在于指定对象实例中

1
2
3
var d = new Date();
d instanceof Date;//=>true d是Date的实例
d instanceof Object;//=>true 所有对象都是Object的实例

区别

  • A.isPrototypeOf(B) 判断的是A对象是否存在于B对象的原型链之中
  • A instanceof B 判断的是 B.prototype 是否存在于A的原型链之中,可以检测 一个对象是否是另一个对象的实例
  • A.isPrototypeOf(B) 为true,则 B instanceof A 一定返回true

怎么遍历一个对象上不是原型上的所有属性呢

hasOwnPropertyNames