原型对象
原型对象可以让所有对象实例共享它所包含的属性和方法。
- 每个构造函数都有一个 prototype 属性,指向它的原型对象;原型对象有一个 constructor 属性,指向该函数
- 用构造函数创建一个新对象后,即实例。这个实例默认有
__proto__
属性,指向构造函数的原型对象
需要注意:
- 函数的
prototype
属性指向函数的原型对象,而不是说prototype
就是原型对象,prototype 是地址,内存中这个地址的位置上的东西才是原型对象- 函数也是对象,所以函数也可以有属性
![image-20210303192201911](/Users/wei/Library/Application Support/typora-user-images/image-20210303192201911.png)
补充
- Prototype 是 构造函数才有,也称为 显式原型
- 所有对象都有 _proto_ , 也叫 隐式原型
- Object.create(null) 创建对象没有 _proto_
- 方法是个特殊的对象,除了有属性 _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 | Person(对象) -> Function.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 | var p = {x:1};//定义一个原型对象 |
instanceof
作用:检测原型链的对象是否存在于指定对象实例中
1 | var d = new Date(); |
区别
- A.isPrototypeOf(B) 判断的是A对象是否存在于B对象的原型链之中
- A instanceof B 判断的是 B.prototype 是否存在于A的原型链之中,可以检测 一个对象是否是另一个对象的实例
- A.isPrototypeOf(B) 为true,则 B instanceof A 一定返回true
怎么遍历一个对象上不是原型上的所有属性呢
hasOwnPropertyNames