JavaScript代码之所以能被执行,是因为JS引擎的存在,在Chrome中,JS引擎为V8。说白了,引擎就是一个程序,实现的功能包括编译(将JS编译成机器能执行的字节码/机器码)、优化、执行和内存回收等。
浏览器为JavaScript代码的执行创造了『运行环境』,提供一系列的API。
所以window实际上是浏览器提供的,并不存在于JS世界,window上这个对象面挂载了console、document、setTimeout……还有Object、Array和Function函数
一般来说,我们创建数组、对象和函数会这么写,其实是简写形式
var person = {}
var array = [1,2,3]
function f(x,y){return x+y}
它们等价于:
var person = new Object({})
var array = new Array(1,2,3)
var f = new Funtion('x','y','return x+y')
根据上面的一堆分析,我们就可以画出下面这张图
接下来再分析图里的prototype和__proto__是什么
首先看下面这段代码
let obj = {}
obj.toString()
obj这个对象没有toString属性,为什么不会报错?
这就涉及到原型和原型链的知识
obj对象有个隐藏属性,也就是上图的__proto__,这个隐藏属性存储了Object.prototype对象的地址
代码执行到obj.toString(),发现obj身上没有toString,就会去隐藏属性对应的对象里面找,于是就找到了Object.prototype.toString
如果再创建一个新对象obj2呢?
let obj2 = {}
obj2.toString()
也是不会报错的,和obj一样,都可以调用.toString()
那么,我们可以得出一个结论
每个对象都有一个隐藏属性
__proto__, 存储着其共有属性组成的对象的地址, 这个共有属性组成的对象叫做原型
原型可以让我们不需要重复声明共有属性
那prototype又是什么呢?
其实,和__proto__的作用一致,都存放了原型的地址
只不过prototype挂在函数上,__proto__挂在每个新生成的对象上
最后总结一下
对象.__proto__ === 其构造函数.prototype
Object.prototype是所有对象的(直接或间接)原型
函数.__proto__ === Function.prototype