先理解两条概念
JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做_ proto _的原型属性,用于指向创建它的 对象 的 原型对象prototype。
原型对象prototype也是一个对象,因此它也有_ proto _ 属性。
图片
- 自己画了一张图,画的比较抽象可能看不懂,下面我会根据图示一点点的来谈谈自己的理解。
1. JS内置对象是Function对象的一个实例。
我们熟知的js的内置对象有:
- String
- Date
- Array
- Math
- RegExp
- Number
- Object
- Null
- Boolean
-
当然也包括Function
如果了解构造函数和构造函数原型的应该知道,每一个函数都会有一个prototype原型对象。当我们实例化这个函数以后,实例化的对象也会有一个_ proto _ 内置属性。此时这个对象的_ proto _ 属性指向的是构造函数的prototype对象。因此这个对象就可以调用构造函数的prototype中的属性和方法。
举个栗子
// 构造函数Person
function Person(name,age) {
this.name = name;
this.age = age;
}
// 实例化一个对象xx
var xx = new Person();
console.log(xx.__proto__ === Person.prototype); // true
// xx是一个对象,而Person是一个函数,我们还可以理解为对象是由函数实例化出来的,因此:
console.log(Object.__proto__ == Function.prototype); //true
- 不光Object,所有内置对象都是Function对象的实例对象,所以他们的_ proto _ 都与Function.prototype相等,也包括Function本身。
<script>
console.log(Number.__proto__ === Function.prototype) // true
console.log(Boolean.__proto__ === Function.prototype) // true
console.log(String.__proto__ === Function.prototype) // true
console.log(Object.__proto__ === Function.prototype) // true
console.log(Function.__proto__ === Function.prototype) // true
console.log(Array.__proto__ === Function.prototype) // true
console.log(RegExp.__proto__ === Function.prototype) // true
console.log(Error.__proto__ === Function.prototype) // true
console.log(Date.__proto__ === Function.prototype) // true
</script>
- 按照上面图片所示的,xx是函数Person一个实例对象,所以xx._ proto _ 指向的就是Person.prototype,即xx._ proto _ === Person.prototype
- 函数本身也是一个对象,所以也包含_ proto _ 属性。同时函数还可以是构造者,包含prototype原型对象。因此:Function._ proto _ === Function.prototype。
- 因为Function._ proto _ === Function.prototype。所以我们可以理解为构造函数Person._ proto _ === Function.prototype。
<script>
function Person(name,age) {
this.name = name;
this.age = age;
}
var xx = new Person();
console.log(xx.__proto__ === Person.prototype); // true
console.log(Object.__proto__ == Function.prototype); // true
console.log(Person.__proto__ == Function.prototype); //true
// 返回的都是true
</script>
2. 内置对象实例的原型指向
- 我们创建一个对象,例如var obj = {}或者是var obj = new Object。都可以看成是实例化了 Object这个内置对象。换而言之,就是内置对象Object构造了obj这个实例对象。
- 现在引出一句很绕口的话:内置对象的实例对象的原型 指向 构造这个实例对象的内置对象的原型。其实理解起来很简单,obj(实例对象)是由Object( 内置对象 )构造的,那么obj._ proto _ === Object.prototype。
<script>
var obj = {name: 'jack'}
var arr = [1,2,3]
var reg = /hello/g
var date = new Date
var err = new Error('exception')
console.log(obj.__proto__ === Object.prototype) // true
console.log(arr.__proto__ === Array.prototype) // true
console.log(reg.__proto__ === RegExp.prototype) // true
console.log(date.__proto__ === Date.prototype) // true
console.log(err.__proto__ === Error.prototype) // true
</script>
3.内置对象的原型对象的原型指向(Object除外)
又是一个很绕口的标题。
内置对象的原型对象,例如:Array.prototype。
内置对象的原型对象的原型就是:Array.prototype._ proto _
如图片所示,是用内置对象Function做了一个栗子,Function.prototype._ proto _ 指向的是 Object.prototype。即:Function.prototype._ proto _ === Object.prototype。
如图片所示,构造函数Person的原型对象。即Person.prototype 对象也有_ proto _ 属性,它也指向Object的prototype。即:Person.prototype__ proto __ === Object.prototype
其余的内置对象也同理。
console.log(Array.prototype.__proto__ === Object.prototype);
//true
// 其余内置对象同理
注意 : Object.prototype._ proto _ = null。
- 内置对象Object.prototype也有_ proto _属性,其为null,并不等于Object.prototype。