荐 【JavaScript核心技术卷】JS的逻辑内存模型
文章目录
JavaScript的逻辑内存模型
Java语言是面向对象的,而JavaScript语言是基于对象的。两者之间是有差异的。这里主要以这两种语言进行一个对比。
一、面向对象的三要素
1.封装 (数据结构 + 算法)
-
Java语言可通过访问修饰符来保证封装性:private。
该类的实例状态应该只能由该类的方法访问修改,否则我们说该类的封装性遭到了破坏。封装性保证了安全和可维护。
JavaScript语言不支持访问权限修饰符,无法隐藏具体实现。 -
JavaScript语言是动态成员, Java语言静态成员。
-
JS中只有实方法(含有隐式形参this)。没有静态方法。
-
JS没有函数重载,形参只是用于便利存取实参。
2.继承
- Java语言只支持静态继承。JavaScript语言支持动态继承。
3.多态
- 多态的前提是继承和虚方法。Java语言支持多态。JavaScript语言无虚函数,所以不支持多态。
我们知道Java语言中有接口类和抽象类,存在接口类和抽象类的继承。而JavaScript语言中无接口类和抽象类。
JavaScript堆中只有对象一种数据结构(一般是哈希表结构),而Java堆中有实例和类两种数据结构。所以,JavaScript是一切皆为对象。
二、JavaScript的逻辑内存模型
逻辑内存模型由执行模型和对象模型组成。
JavaScript的逻辑内存模型是比较复杂的。
执行模型
可执行的JavaScript代码分三种类型:
- Global Code,即全局的、不在任何函数里面的代码,例如:一个js文件、嵌入在HTML页面中的js代码等。
- Eval Code,即使用eval()函数动态执行的JS代码。
- Function Code,即用户自定义函数中的函数体JS代码。 不同类型的JavaScript代码具有不同的Execution Context
在一个页面中,第一次载入JS代码时创建一个全局执行环境,当调用一个 JavaScript 函数时,该函数就会进入相应的执行环境。如果又调用了另外一个函数(或者递归地调用同一个函数),则又会创建一个新的执行环境,并且在函数调用期间执行过程都处于该环境中。当调用的函数返回后,执行过程会返回原始执行环境。因而,运行中的 JavaScript 代码就构成了一个执行环境栈。执行模型就是对JS代码执行环境的一个描述
对象模型
JS中一切皆对象,对象模型就是对代码中对象以及对象之间关系的一种抽象描述
对象中的[[]]属性是内置的隐式属性,有JS引擎添加
- 内部隐式属性[[Class]]的值为”Function”,说明该函数对象的类名称是”Function”
- 内部隐式属性[[Extensible]] 的值为 true,说明该函数对象的属性可以增删
- 内部隐式属性[[Prototype]]为Function .prototype,说明该函数对象是类Function的实例
- 内部隐式属性[[Call]],它是由用户JS代码实现的用户方法
- 内部隐式属性[[Construct]],它是由JS引擎用native code 或内置JS代码实现的内部方法
- 内部隐式属性[[Scope]]设置函数对象的作用域链:
- 用function关键字声明的函数声明语句创建的函数对象,其[[Scope]]静态作用域链复制当前执行环境的执行作用域链
- 使用function关键字声明的匿名函数表达式创建的函数对象,其[[Scope]]静态作用域链复制当前执行环境的作用域链
- 使用function关键字声明的命名函数表达式创建的函数对象,其[[Scope]]静态作用域链复制当前执行环境的作用域链;在[[Scope]]静态作用域链的前端添加一个Object类的实例;在该实例上添加一个属性,名字为函数名functionName,值为返回的函数对象fn。
var test = function functionName(a){document.write(a + "<br />");}
- new Function()、Function()函数创建的函数对象的[[Scope]]静态作用域链永远复制全局执行环境的作用域链,只包含window对象。
var fn = new Function("形式参数1","形式参数2",...,"形式参数n","函数体");
var fn = Function("形式参数1","形式参数2",...,"形式参数n","函数体");
剩下的了解:
- create():使用指定的原型对象和属性创建一个新对象
- seal():密封对象, 对象数据属性的[[configurable]]为false,即不能删除对象的属性和方法
- freeze():冻结对象,对象数据属性的[[writable]]为false,即不能删除或更改对象的属性
- preventExtensions:调用此方法后不能给对象添加新属性和方法
- issealed:判断对象是否密封
- isFrozen:判断对象是否冻结
- isExtensible:检测对象是否可扩展
- getPrototypeOf:得到对象的原型
- keys:返回对象的自身可枚举属性组成的数组
- getOwnPropertyNames:返回对象的自身属性的属性名(包括可枚举属性但不包括Symbol值作为名称的属性)
- length:属性,作为函数使用时,参数的长度
- caller:属性,作为函数使用时,其调用者
- arguments:属性,作为函数使用时,参数列表
我们和Java的对比一下:
三、JavaScript的对象与Java的实例
中括号内放置的是引擎给加的隐式属性,必包括3个(Prototype指针,Class字符串/类名,Extensible/属性是否可增删),只包括这三个隐式属性的是对象
四、window对象的内存逻辑模型
与全局执行环境对象关联的变量对象(Variable Object)在JS中称为全局对象(Global Object),JS规定其一定是一个宿主对象,在Web中,为window对象。我们编写的JS代码可以访问window对象。全局执行环境直到应用程序退出—例如关闭网页或浏览器—时才会被销毁。相当于Java的常量池。
与全局执行环境对象关联的变量对象(Variable Object)在JS中称为全局对象(Global Object),JS规定其一定是一个宿主对象,在Web中,为window对象。我们编写的JS代码可以访问window对象。全局执行环境直到应用程序退出—例如关闭网页或浏览器—时才会被销毁。相当于Java的常量池
五、Object构造函数的内存逻辑模型
相当于Java中的Object类。有两个对象结构组成。
原型对象中的方法和属性都是可以被继承的 类对象中放置的都是静态属性,可以直接通过类调用 可以根据constructor属性区分类对象与原型对象:原型对象有constructor属性,没有prototype属性,类对象则相反
六、Function构造函数的内存逻辑模型
相当于Java中的Class反射类。有两个对象结构组成。
JS中一切皆对象,所以Function也是Object的实例,Function.prototype指向Object的原型
七、JavaScript的类继承
继承的实质是指JS对象的原型指向其父类
八、JavaScript的对象与类
JS的原型对象+类对象相当于java的类
Thanks for 【进阶er】’ help
本文地址:https://blog.csdn.net/qq_42322103/article/details/105626889