浅谈javascript中变量作用域和内存(1)
先理解两个概念:基本类型和引用类型的值
1、基本类型和引用类型的值
(1)定义:
基本类型:指简单的数据段,比如按值访问的js五种基本数据类型undefined、null、boolean、number、srtring
引用类型的值:指保存在内存中的对象,注意一点,js不允许直接操作对象的空间
(2)相似和区别:
相同:定义两种类型的方式都类似:创建一个变量并赋值
不同点1:对于引用数据的值,我们可以添加属性进去,但是基本类型不行,强行添加会报undefined
下面给个例子:
var person = new Object()
person.name = "saebr";
console.log(person.name)//saber
而基本类型添加属性会报undefined:
var name = "saber";
name.sex = "女";
console.log(name.sex)//undefined
不同点2:变量的复制也不相同:
var num = 777;
var num1 = num;
console.log(num1)//
基本类型的复制,简单来说就是用num的值来初始化num1,num1中也保存了值777,但是num和num1保存的777是两个完全独立的。
var obj = new Object();
var obj1 = obj;
obj.name = "saber";
console.log(obj1.name)//saber
而引用类型的复制,最简单的话来说就是obj保存了一个对象的新实例,复制的过程就是让obj1的指针也指向这个对象,因此改变其中一个变量就会影响到另外一个变量。
不同点3:参数传递的不同
传递基本类型的值时,被传递的值会被复制给一个局部变量,而传递引用类型的值时,会把值得内存的地址复制给局部变量,这么说可能不好理解,撸两个例子看看:
首先是基本类型的传递参数:
function add(num) {
num += 1;
return num;
}
var saber = 7;
var archer = add(saber);
console.log(saber)//
console.log(archer)//
使用数值等基本类型来传参,函数内部的不会影响外部saber的变量,因为num和saber互相不认识,他们仅仅有相同的值,也就是如同上面所说的是完全独立的。
其次是引用类型的传递参数:
var person = new Object();
function setName(obj){
obj.name = "saber"
};
setName(person);
console.log(person.name)//saber
看上去好像引用类型的传递参数是按引用传递,第一次看上去好像是这么回事,在局部作用域里面修改对象,会在全局作用域里展现出来,所以误认为是按引用传递。
实际上js都是按值来传递参数的,上面的基本类型就不说了,简单明了,下面写个例子证明一下,引用类型是按值传递的:
var person = new Object();
function setName(obj){
obj.name = "saber"
obj = new Object();
obj.name = "archer"
};
setName(person);
console.log(person.name)//saber
也就是说如果是按引用传递的话,person会被修改为指向name属性值为archer的新对象,但是结果是saber,这已经说明了一切。事实上,当函数执行完毕,这个archer的局部对象会被立即销毁。
(3)检测引用类型
检测基本数据类型使用typeof,那么如何检测引用类型呢?
所有引用类型的值都是Object的实例,escript提供了instanceof来检测引用类型和Object构造函数,如果是的话,返回true;
2、作用域
首先,要了解一个概念,全局执行环境被认为是windows对象,然后,每个函数都有自己的执行环境,当执行流进入一个函数时,这个函数的环境就会被推入一个环境栈中,当执行完,就会退出这个环境栈,然后返回之前的执行环境
作用域链
所以,当代码在一个环境中执行时,就会创建一个对象的作用域链。简单说一下作用域链,作用域链的下一个变量对象来自于外部环境,再下一个变量对象又来自更外一层的环境,这样一层一层直到最外层的全局执行环境windows。
还是撸一串代码看看,光说根本一连懵逼呀:
var SName = "saber";
function changeSavant(){
var AName = "archer";
// console.log(SName)//saber
// console.log(AName)//archer这里可以访问两个,访问不了beateSavant里面的LName
beateSavant();
function beateSavant(){
var LName = AName;
AName = SName;
SName = LName;
console.log(SName)//archer
console.log(AName)//saber
console.log(LName)//archer这里三个都可以访问到
}
}
// console.log(SName)//saber这个地方只能访问到SName
// console.log(AName)//AName is not defined
changeSavant();
简单来说,可以看到,函数内部的可以访问到外部的,但是外部的无法访问到内部的变量,那么这是如何访问到的呢,所以这就是作用域链的作用,首先函数的局部环境会先在自己的环境中搜索变量和函数名,搜索不到就再搜索上一层的作用域链。
这下是不是简单明了了很多~
延长作用域链
js有两种方式来延长作用域链:
(1)try catch中的catch
function add() {
try{}
catch{}//延长的作用域链
}
(2)with
浅谈javascript中变量作用域和内存(1)的更多相关文章
- 浅谈javascript中变量作用域和内存(2)
1.无块级作用域 javascript没有块级作用域,这会让其他程序员在理解js代码上很痛苦.在其他很多语言,比如C,大括号括起来的代码块都有自己的作用域 举个例子 if(true) { var na ...
- 浅谈javascript中的作用域
首先说明一下:Js中的作用域不同于其他语言的作用域,要特别注意 JS中作用域的概念: 表示变量或函数起作用的区域,指代了它们在什么样的上下文中执行,亦即上下文执行环境.Javascript的作 ...
- 浅谈javascript的变量作用域
1.变量遵循先声明再使用. console.log(b); b=123; 代码运行结果: Uncaught ReferenceError: b is not defined 2.方法内定义的局部变量外 ...
- 浅谈JavaScript中的闭包
浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...
- 浅谈JavaScript中的null和undefined
浅谈JavaScript中的null和undefined null null是JavaScript中的关键字,表示一个特殊值,常用来描述"空值". 对null进行typeof类型运 ...
- 浅谈JavaScript中的正则表达式(适用初学者观看)
浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...
- 浅谈JavaScript中的变量、参数、作用域和作用域链
基本类型和引用类型 在JavaScript中有两种数据类型值.基本类型值和引用类型值.基本类型值指的是简单的数据段,而引用类型值指的是可能由多个值构成的对象.在JavaScript中有5种基本数据类型 ...
- 浅谈JavaScript中的内存管理
一门语言的内存存储方式是我们学习他必须要了解的,接下来让我浅谈一下自己对他的认识. 首先说,JavaScript中的变量包含两种两种类型: 1)值类型或基本类型:undefined.null.numb ...
- 浅谈JavaScript中闭包
引言 闭包可以说是JavaScript中最有特色的一个地方,很好的理解闭包是更深层次的学习JavaScript的基础.这篇文章我们就来简单的谈下JavaScript下的闭包. 闭包是什么? 闭包是什么 ...
随机推荐
- Android平台签名证书(.keystore)生成指南
来源:https://ask.dcloud.net.cn/article/35777 Android平台签名证书(.keystore)生成指南 分类:HTML5+ Android证书 Android平 ...
- python 调用java脚本的加密(没试过,先记录在此)
http://lemfix.com/topics/344 前言 自动化测试应用越来越多了,尤其是接口自动化测试. 在接口测试数据传递方面,很多公司都会选择对请求数据进行加密处理. 而目前为主,大部分公 ...
- matlab基本函数inf, isempty, round, floor, fix
一起来学演化计算-matlab基本函数inf, isempty, round, floor ,fix 觉得有用的话,欢迎一起讨论相互学习~Follow Me inf matlab中 inf无穷大量+∞ ...
- SpringBoot 获取配置 @Value
@Value注解可以在代码中直接取到相应的值 如在application.yml中 # 自定义属性 leysen: xcx: url: aaa 1.java代码里的属性值是非静态的,直接在属性上加@V ...
- Spring Boot 使用MockMvc对象模拟调用Controller
功能实现之后,我们要养成随手写配套单元测试的习惯,这在微服务架构中尤为重要.通常,我们实施微服务架构的时候,已经实现了前后端分离的项目与架构部署.那么在实现后端服务的时候,单元测试是在开发过程中用来验 ...
- C# .NET WINFORM MUTEX 互斥
static class Program 里的全局变量: static System.Threading.Mutex appMutex; Main 方法里的内容: string exeName = & ...
- 超类Object
Object:是类层次结构中的跟类,所有类都直接货间接继承自该类 如果一个方法的形参是Object,那么这里我们就可以传递它的任意的子类对象,相当于传任何数据类型都可以 toString()——返回地 ...
- php面向对象(目录操作)
目录操作 创建目录 Mkdir(目录地址,权限,是否递归创建=false); Rmdir(目录地址) 删除目录 仅仅可以删除空目录.(不支持递归删除) 移动(改名) Rename(旧地址,新地址) 该 ...
- Mowing the Lawn【线性dp + 单调队列优化】
题目链接:https://ac.nowcoder.com/acm/contest/2652/G 题目大意:与上一篇博客 烽火传递 差不多. 1.一共n头羊,若超过m头连续的羊在一起,就会集体罢工,每头 ...
- Cookies和Sessions
Cookie和Session 为什么会有cookie和session? 由于http协议是无状态的 无法记住用户是谁,cookie主要是在浏览器上记录客户的状态,session主要是用来在服务端记录客 ...