js有三种内存 一是函数 二是函数的栈 三是对象或者说堆 各有特点
有很多很多堆 每一个函数都是在某个堆上工作 它可以在这个堆上增加某个可以引用的对象(通过this.变量=XXX) 或者使用父堆(通过__proto__)
对象有子对象 就好像一棵有无数对象和函数对象的森林(tree结构)
每个建立的对象都有__proto__,指向它继承的对象,对象通过__proto__链可以继承其他对象的方法和成员的实例,可以比较轻松地迁移到其他对象分支
在浏览器环境下 window代表所有堆的根
(function() { … })() 这些写可以创建一个匿名的堆 这个匿名的堆挂在最近的堆的子堆 避免污染
函数可以通过prototype添加子函数(比如函数名.prototype.子函数名=function (){})和改造构造函数(prototype.constructor) 所以说函数也可以建成一个森林
所以函数可以在prototype下面建立很多东西 而prototype指向函数这个对象
函数的prototype还有一个constructor函数 表示构造函数 所以这个constructor函数指向函数
函数的prototype相当于函数的父空间 函数可以通过“函数名.prototype.子函数名=function (){}”这种方法来继承某个子函数 还可以通过“函数名.prototype=某个object”来继承某个object的所有成员名称和方法
所以说__proto__和prototype本质是一样的,都表示父空间,只是一个作用于对象,一个作用于函数,但是函数只是在运行的时候才有值,所以还是有很大不一样
apply,call,bind可以让函数使用某个对象堆分支
栈是在运行中增长和消减的 一个函数无法使用另一个函数的栈
通过new或者object.create 可以 创建将一个函数转化为对象或者说堆 new的过程中执行这个函数 对这个堆进行操作
总结:js可以构建一个对象和函数的森林,可以比较轻松地迁移对象和函数分支,比较类似lisp
推荐阅读:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype