前言
众所周知在js中分Undefined
、Null
、Boolean
、Number
和String
五种基本数据类型和一种复杂数据类型Object,基本数据类型因为大小固定的关系,在栈内存中按值存放,复杂数据类型在栈中保存的是一个指针变量,指向堆内存中的某个对象。
接下来是本文的重点,探讨复杂数据类型在js中的关系。
Function和Object
在程序员的世界,万物皆对象,在js中又以函数作为一等公民,也就是说在js的世界中对象往往是以函数的形式存在,没错,Object也是函数Function。
如果说Function instanceof Object为true还可以理解的话,那Object instanceof Function为true又是怎么回事?
画得不好请见谅,可以沿着紫红色的箭头一直走到null对象,这也是原型链的顶端。
如果新来的同学对prototype和__proto__不够了解的话,记住下面这句话:
prototype
说的是构造函数和原型对象之间的关系,__proto__
说的是实例对象和原型对象之间的关系。
验证如下:
蓝色箭头同理,只不过把__proto__换成constructor,大家可以自己打开浏览器F12尝试一下。
var xiaoming = {
name: "xiaoming",
age: 12,
score: 100,
say: function() {
console.log("我妈常说我考满分!")
}
}
当我们用上面的方式自面量声明时,就隐式创建了一个Object对象小明同学,他有一个say函数和几个属性,创建好之后关系如下:
验证如下:
总结
比较绕的地方应该就是Object与Function的关系,还记得那句话吗?
prototype
说的是构造函数和原型对象之间的关系,__proto__
说的是实例对象和原型对象之间的关系。
因为函数既是函数又是对象,声明的函数与声明的非函数对象关系已经在最后部分展示了,前提是原型链和constructor对象都没有发生改变。
因为本文暂时没有涉及原型链指向的改变和new构造函数,所以讨论的关系还比较简单,希望认真读完的你有所收获!