js的原型系统中,有三个很重要的属性,constructor,proto,prototype,做了一张图,梳理一下它们之间的关系。

javascipt中的数据类型分为原始类型对象类型。
原始类型包括

  • 字符串
  • 数字
  • 布尔值
  • undefined
  • null

除了这五种,其余的都是对象类型了。对象类型中包含一个特殊的类型 —— 函数。 而通过构造函数又可以生成对象。

原始类型与对象类型的联系

在读写字符串,数字,布尔值的时候,它们都是原始值,既然如此,它们就不应该有属性和方法,但事实却并非如此。

var x = 'abcde';
var y = x.substring(2); // cde

这里x是一个原始类型,但是它确可以调用方法。why? 这是因为为了方便操作原始类型,js中引入了包装对象。 它可以通过String(), Number(), Boolean()这三个构造函数显式的创建 在操作一个原始类型的时候,js会默默地调用上面三个构造函数,产生一个包装对象,然后它会从原型上继承一些方法,一旦操作完成,这个包装对象就会被销毁。拿上面的例子来说 **var y = x.substring(2);**相当于

	var temp = new String('abcde');
	var y = temp.substring(2);

关键属性

  • constructor指向对象实例的构造函数
  • __proto__以前是一个没有标准化的属性,但是在ECMAScript 2015里已经标准化了,各大现代浏览器也支持,它指向对象的原型对象
  • prototype 这个属性只有函数才有,当一个构造函数实例化了一个对象以后,这个对象的原型就是由这个构造函数的prototype

系统

原始类型

原始类型不是对象,所以它不会有属性和方法,但是按照前文提到过的包装对象,我们可以像操作对象一样去操作原始类型,除了undefined和null这两者不能创造包装对象,其余原始类型的原型链结构差不多。

  • 字符串
    constructor -> String()
    __proto__ -> String.prototype
    没有prototype
  • 数字 constructor -> Number()
    __proto__ -> Number.prototype
    没有prototype
  • 布尔值 constructor -> Boolean()
    __proto__ -> Boolean.prototype
    没有prototype

函数

使用new Function()来定义的函数:
显而易见,这种函数的constructor就是它

使用变量赋值或者关键字定义的函数
看起来这种函数并没有构造函数,但它情况与原始值会创建包装对象是一样的,js会使用new Function()隐式的生成一个包装对象,所以这种函数的constructor也是Function ();

这两者的prototype对象不同,但是 __proto__是一样的,并且都指向Function的prototype

对象

构造函数生成的对象 它的constructor是这个构造函数,它没有prototype,他的__proto__指向构造函数的prototype

字面量生成的对象 由于隐式调用了new Object(),所以它constructor是Object(),它的__proto__是Object.prototype

function man (name, age) {
	this.name = name;
	this.age = age;
}
var person1 = new man('peter', 22);
var person2 = {
	name: 'tim',
	age: 33
}
person1.constructor // function man (name, age) {...}
person2.constructor // function Object() {...}

内置构造函数

Function 是一个特例
Function ()的constructor是它本身
他的__proto__和prototype相同,并且都指向一个匿名函数,这个函数的表现在不同的浏览器内核下不同
这里匿名函数的的__proto__指向了Object.prototype

Object也是一个特例
它的constructor是Function,因为本质上它也是个函数
它的prototype是一个特殊的原型对象,这个原型对象的__proto__是null
它的的__proto__和Function一样

其他的几个内置构造函数的constructor是Function(), __proto__是Function的prototype,也就是说都是那个匿名函数