原型
- 定义函数时,解析器会为它添加一个
prototype
属性,默认总是指向一个对象,即原型对象。- 如果把函数作为普通函数调用,
prototype
不会有任何作用; - 原型对象默认只会获得一个
constructor
属性,指向函数自身,其他所有方法都继承自Object
function Person() {} Person.prototype.constructor === Person // true
- 如果以构造函数的形式调用,它创建的对象中都会隐式包含一个指针
[[Prototype]]
,它指向构造函数的原型对象,而且这个指针不能访问。 - 在
Safari、Firefox、Chrome
浏览器中,会为每个对象暴露一个名为__proto__
的属性,通过这个属性来访问构造函数的原型对象。 - 原型对象也是一个对象,也会有一个
__proto__
属性,默认指向顶层对象Object
的原型对象Person.prototype.__proto__ === Object.prototype // true
-
Object
既然是顶层对象,那么它的原型对象中的__proto__
就没有指向了Object.prototype.__proto__ = null
- 如果把函数作为普通函数调用,
-
prototype
又称为显式原型,__proto__
又称为隐式原型。 -
Object
和Function
也是构造函数-
Object
处在JavaScript
中的顶层,它的原型对象中定义了一些基本的方法,诸如hasOwnProperty、isPrototypeOf、toString...
,而这些方法是供对象使用的,对象通过原型链(__proto__
)找到这些方法; -
Function
的原型比较特殊,它不是一个对象,而是指向一个函数体,它上面除了具有constructor
和__proto__
这两个属性之外,还定义了函数的一些基本属性和方法,诸如apply、arguments、bind、call、caller、length、name...
Function.prototype // ƒ () { [native code] } Function.prototype.constructor === Function // true Function.prototype.__proto__ === Object.prototype // true
-
-
JS
的函数也是一种对象,包括Object
和Function
,函数的__proto__
指向Function
的原型,所以函数都可以通过原型链访问Function
的原型上定义的属性和方法。
Person.__proto__ = Object.__proto__ = Function.__proto__ = Function.prototype
原型链
原型链体现在 __proto__
属性的作用上。
当访问一个对象的属性(或方法)时,如果该对象内部不存在这个属性,那么就会去它的__proto__
属性所指向的原型对象里找,直到__proto__
属性的终点Object.prototype.__proto__ = null
,再往上查找会报错。通过__proto__
属性将连接起来的这条链路就是所谓的原型链。
总结
-
prototype
属性是函数所独有的,__proto__
属性是对象所独有的,因为函数和原型也是一种对象,所以它们也拥有__proto__
属性; -
prototype
属性的作用就是让该函数所实例化的对象们都可以找到公用的属性和方法,即f1.__proto__ === Foo.prototype
。 - 原型对象上默认会有一个
constructor
属性,指向构造函数自身,所有函数的顶层构造函数都指向Function
-
prop in obj
:检查对象obj
是否有属性prop
,如果对象中没有,会检查原型链; -
obj.hasOwnProperty(prop)
:只检查对象自身中是否有某个属性; -
A instanceof B
的判断标准:如果B
的显示原型在A
的原型链上,则返回true
。如果A
是基本数据类型,直接返回false
。
Function instanceof Object // true
Object instanceof Function // true
原型链神图
其实只需要注意以下几点:
- 原型链是通过隐式原型
__proto__
查找的,尽头是Object.prototype
,再向上Object.prototype.__proto__ = null
-
Function
的隐式原型和显示原型指向同一个对象!这是独一无二的!Function.__proto__ === Function.prototype -> [native code]
-
Object
是所有对象的顶层父类,包括Function
// Function的原型链 Function.__proto__ -> Function.prototype -> Function.prototype.__proto__ -> Object.prototype
-
Function
是所有函数的顶层父类,所有函数的派生自Function
,包括Object
Object.__proto__ -> Function.prototype