1. 明确一些概念:
1. 什么是堆?什么是栈?
-
堆(heap)是不连续的内存区域,即数据可以任意存放, 主要存放的是对象等。
-
栈(stack)是一块连续的内存区域,每个区块按照一定次序存放(后进先出),栈中主要存放的是基本类型的变量的值以及指向堆中的数组或者对象的地址
2. JS有七种数据类型:数字number、字符串string、boolean布尔、符号Symbol、null、undefined、对象object。
-
“类型”是JS数据的分类,分7种,“类”是针对于对象的分类,有无数种
-
其中又可以分为两类:基本数据类型(非对象)和引用数据类型(对象)。
- 基本数据类型:数字number、字符串string、boolean布尔、符号Symbol、null、undefined
- 引用数据类型:对象object
基本数据类型存储在栈stack,引用数据类型存储在堆heap
2. 原型
所有的引用类型(数组、对象、函数)都有__proto__这个属性。构造函数拥有prototype属性
prototype显式原型,__proto__隐式原型。
构造函数对象才有prototype属性, 实例具有__proto__属性,他们指向的都是堆区中的原型对象(prototype和__proto__保存都是堆区中原型对象的地址,并且是一样的地址,所以构造函数.prototype===实例对象.__proto__)
原型对象是所有实例共享的,并且每个实例都可以调用原型上的函数方法
Object.prototype是所有对象的(直接或者间接)原型,对于数组、函数来说,是间接原型,但是对于对象,是直接原型
所有函数对象都是由Function构造的
函数对象.__proto__===Function.prototype
构造函数有Object/Array/Function
3. 原型链
实例可以直接调用原型上的属性和方法,如果没有,就去原型的原型里找,再没有,就去原型的原型的原型里找,于是形成了原型链
原型链的终点是null
JS世界:
xxx的原型指的是xxx的__proto__
首先有一个根对象、一个函数原型、一个数组原型。函数原型和数组原型的原型(__proto__)为根对象。
然后创建Function构造函数,__proto__为函数原型,Function.prototype也为函数原型(Function的prototype和__proto__指向同一对象即函数原型)。
接着开始用Function构造Object和Array,分别让他们的prototype为根对象和数组原型。至此JS世界创建完毕,最后用window对象里的三个属性Object、Array、Function分别保存指向前面创建的Object、Array、Function函数对象
Object.prototype是由Function构造的,但是并不是说Object是Function构造的,Object.prototype只是个Function构造出来的地址,Function添加了这个指向prototype对象的地址,prototype指向的对象才是根对象
以上内容参考自饥人谷课程