js:变量,作用域以及内存问题

最近在重读《javascript高级程序设计》这本书,“温故而知新”,古人诚不欺我,再看的时候发现很多知识是之前不理解便跳过的,也有很多之前只是知道并记住了,并不能形成一套体系,而不断的回顾,不断地总结,我发现有很多零零散散的知识点在不经意间就被串在了一起,恍然大悟的感觉甚是美妙

而我一向喜欢思维导图和记忆的方式去学习总结,在用文字表达和总结方面显得很贫乏,所以打算用这种博客的形式来记录下重读过程中的总结,就当是记个笔记,也顺便练练表达能力

变量:

js中的变量可能包含两种不同数据类型的值:分为基本类型值和引用类型值。两者区分的本质是取决于变量在内存中的存储方式,基本类型值存放在栈内存中,引用类型值保存在堆内存中。

而由于两种类型的保存方式不同,我们在复制变量值的时候就会发现:对基本类型值的复制是值复制,复制后的变量值与变量值只是数据相同而且,在内存中是独立的;对引用类型值的复制是其实也是“值”复制,不过这个值是一个指针,而我们真正会操作的数据是指针指向的一个内存,我们复制的那个指针“值”只是一个指向真正数据内存的地址,也就是我们常说的引用,所以,在引用类型的复制中,最终复制后的变量与复制前的变量指向同一数据,所以对其中任何一个变量进行改变都会影响另外一个

目前简单数据类型有:Undefined,Null,String,Number,Boolean,Symbol(es6新增数据类型)

复杂数据类型:Object

而对简单数据类型,通常用typeof来判断,其返回值有:“undefined”,“string”,“number”,“boolean”,“symbol”,“function”,“object”而typeof null == “object”,是因为历史遗留问题,而本身null也表示“该变量为一个空的指针”,所以,其typeof的结果为“object”也可以理解了

而对复杂数据类型,通常使用instanceof来判断,表示是否是该对象的实例对象,通过原型链(暂不做讨论)来判断

而对一些特殊的数据类型,我们也有对应的方法判断其类型:数据的Array.isArray,非数字的isNaN

执行环境与作用域:

首先,明确几个知识点:1)每个函数都有自己的执行环境  2)执行环境定义了变量或函数有权访问的其他数据  3)每个执行环境都有一个与之关联的变量对象,执行环境中定义的所有变量和函数都保存在这个对象中

对以上三点我所理解的就是:每个函数在内存中都有一个与之关联的对象,该对象中保存了这个函数内部定义的变量,方法等一切信息,是对这个函数的一个描述对象

而当函数执行时,函数的执行环境会被推入到一个环境栈中,此时会形成与其他执行环境的一种“包含”或者“平行”的关系,而这种“包含”的体现就是“作用域链”,更严谨的说法是:当代码再一个环境中执行时,会创建变量对象的一个作用域链。而作用域链的作用就很牛逼了,我们经常说的变量查找从局部作用域到外层再到外层直至全局作用域就是依靠这条作用域链。作用域链只能向上查找。

内存问题

js的垃圾回收机制使得执行环境会管理代码执行过程中使用的内存,而按照我们对执行环境和作用域的理解,我们知道,代码执行结束后,执行环境被从环境栈中推出,此时执行环境中的局部变量也就没有存在的意义了,所以,此时需要告知该执行环境中的局部变量应该被回收,而具体的回收策略在浏览器中有:

1:标记清除:变量的标记从“进入执行环境”到“离开执行环境”,回收机制只要清除那些标有“离开”的变量即可

2:引用计数:当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数加1,如果同一个值又被赋给另外一个变量,则减1,回收机制负责回收引用次数为0的值。但是这种方法遇到循环引用时,便会陷入僵局,所以,该方法使用场景较少

越写越乱的感觉,表达能力还是太欠缺了,还需要多练习,对知识也要深入理解,加油!!!

原文地址:https://www.cnblogs.com/waiting-h/p/9048865.html

时间: 2024-10-17 10:49:05

js:变量,作用域以及内存问题的相关文章

js变量作用域

? 1 2 3 4 5 6 7 8 9 10 for(var i =0;i<100;i++)   {        } alert(i);//100 if(true){     var i="91d";   } alert(i);//91d ? 1 2 3 4 5 6 function add(ad1,ad2){   sum=ad1+ad2;   return sum;//如果没有用var声明局部变量,会提升为全局的变量 } alert(add(3,5)); alert(&quo

第一百零六节,JavaScript变量作用域及内存

JavaScript变量作用域及内存 学习要点: 1.变量及作用域 2.内存问题 JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只是在特定时间用于保存特定值的一个名字而已.由于不存在定义某个变量必须要保存何种数据类型值的规则,变量的值及其数据类型可以在脚本的生命周期内改变. 一.变量及作用域 1.基本类型和引用类型的值 ECMAScript变量可能包含两种不同的数据类型的值:基本类型值和引用类型值.基本类型值指的是那些保存在栈

javascript变量作用域与内存

第四章 变量作用域与内存基本类型 5种Undefined Null Boolean Number String 两种变量类型 基本类型与引用类型注意:String 再其他语言中是引用类型,再javascri中为基本类型即:这五种基本类型是按值访问的 引用类型是按照引用访问的 动态的属性对于一个引用类型,一个引用变量被赋值后,可以为其添加属性,也可以删除与修改其属性var o = new object();o.name = "qi"; //可以为引用变量添加属性 变量的复制基本类型的复制

[刘阳Java]_步步窥探JS变量作用域

今天的这个文章题目名称甚是让人会突发异想.JS变量作用域是务必需要搞懂的,单从面试过程就会让面试者烧脑壳.所以,我们还是写一篇关于JS变量作用域的技术专题,让所有小伙伴能够借此文章去整理JS的基础学习.说不定很多人会比我理解这方面基础知识有更好地见解 黄金守则第一条: JS没有块级作用域(你可以自己闭包或其他方法实现),只有函数级作用域,函数外面的变量函数里面可以找到,函数里面的变量外面找不到 <!doctype html> <html lang="en"> &

JavaScript变量作用域和内存问题(js高级程序设计总结)

1,变量 ECMAScript和JavaScript是等同的吗?个人认为是否定的.我的理解是这样的,ECMAScript是一套完整的标准或者说协议,而JavaScript是在浏览器上实现的一套脚本语言.也就是说,ECMAScript是JavaScript的父类标准.JavaScript是ECMAScript的具体实现.所有ECMAScript定义的数据类型或者语言特性实际上都是伪代码的形式规定的.当然如果可以,ECMAScript也可以有服务器实现,单片机实现(不一定恰当).如果说ECMAScr

javaScript的闭包 js变量作用域

js的闭包 js的变量作用域: var a=90; //定义一个全局变量 function test(){ a=123; //使用外层的 a变量 } test(); document.write("a="+a); var a=90; //定义一个全局变量 function test(){ var a=123; //定义一个局部变量 } test(); document.write("a="+a); a=90; //没有var ,就会试着去找(父函数 的 a),如果找

原型模式故事链(5)--JS变量作用域、作用域链、闭包

上一章 JS执行上下文.变量提升.函数声明 传送门:https://segmentfault.com/a/11... 本次我们主要讲讲变量作用域和闭包变量作用域:顾名思义:变量起作用的范围.变量分为全局变量和局部变量.全局变量:在任何地方都能用,在所有函数之外.局部变量:只能在定义它的函数中,以及它的子函数中使用. 当前作用域没有定义的变量,称为自由变量. 举例子: <!DOCTYPE html> <html> <head> <title>dsfg</

js变量作用域--变量提升

1.JS作用域 在ES5中,js只有两种形式的作用域:全局作用域和函数作用域,在ES6中,新增了一个块级作用域(最近的大括号涵盖的范围),但是仅限于let方式申明的变量. 2.变量声明 1 var x; //变量声明 2 var x=1; //变量声明并赋值 3 x = 1; // 定义全局变量并赋值 3.函数声明 function fn(){}; //函数声明并定义 var fn = function(){}; // 实际上是定义了一个局部变量fn和一个匿名函数,然后把这个匿名函数赋值给了fn

JS 变量作用域

变量作用域 有作用范围和生命周期. 静态作用域: 词法作用呀,由程序的定义位置决定,在编译的时候就决定了生存周期和作用范围. 跟代码执行顺序无关,通过代码嵌套来解析. 例子: var x = 10; function fun () { //编译的时候,X已经初始化了. alert(x); } function foo () { var x = 20; fun(); //运行fun的时候,x已经编译过了,就是10 } foo(); //10 动态作用: 程序运行时决定的.类似于C++的动态绑定.

js 变量作用域 与 this

首先说下js作用域链:由于js变量都是对象的属性,对象又可以是对象的属性,最终到达window,所以变量-------window就是一条作用域链: 先说下变量作用域: var a=10;function test(){ console.log(a);----------undefined var a = 5; console.log(a);----------5}test(); test() 方法内:console.log(a)中变量a寻找自己的定义,发现var a = 5;已经有定义了,所以