深入理解 JavaScript中的变量、值、传参
1. demo
如果你对下面的代码没有任何疑问就能自信的回答出输出的内容,那么本篇文章就不值得你浪费时间了。
var var1 = 1
var var2 = true
var var3 = [1,2,3]
var var4 = var3
function test (var1, var3) {
var1 = 'changed'
var3[0] = 'changed'
var3 = 'changed'
}
test(var1, var3)
console.log(var1, var2, var3, var4)
2. 深入理解原始类型
原始类型有5个 Undefinded, Null, Boolean, Number, String
2.1. 原始类型变量没有属性和方法
// 抬杠, 下面的length属性,toString方法怎么有属性和方法呢?
var a = 'oooo'
a.length
a.toString
原始类型中,有三个特殊的引用类型Boolean
, Number
, String
,在操作原始类型时,原始类型变量会转换成对应的基本包装类型
变量去操作。参考JavaScript高级程序设计 5.6 基本包装类型。
2.2. 原始类型值不可变
原始类型的变量的值是不可变的,只能给变量赋予新的值。
下面给出例子
// str1 开始的值是aaa
var str1 = 'aaa'
// 首先创建一个能容纳6个字符串的新字符串
// 然后再这个字符串中填充 aaa和bbb
// 最后销毁字符串 aaa和bbb
// 而不能理解成在str1的值aaa后追加bbb
str1 = str1 + 'bbb'
其他原始类型的值也是不可变的, 例如数值类型的。
2.3. 原始类型值是字面量
3. 变量和值有什么区别?
不是每一个值都有地址,但每一个变量有。
《Go程序设计语言》变量没有类型,值有。变量可以用来保存任何类型的值。
《You-Dont-Know-JS》
变量都是有内存地址的,变量有用来保存各种类型的值;不同类型的值,占用的空间不同。
var a = 1
typeof a // 检测的不是变量a的类型,而是a的值1的类型
4. 变量访问有哪些方式?
变量访问的方式有两种:
按值访问
按引用访问
在JS中,五种基本类型Undefinded, Null, Boolean, Number, String
是按照值访问的。基本类型变量的值就是字面上表示的值。而引用类型的值是指向该对象的指针,而指针可以理解为内存地址。
可以理解基本类型的变量的值,就是字面上写的数值。而引用类型的值则是一个内存地址
。但是这个内存地址,对于程序来说,是透明不可见的。无论是Get还是Set都无法操作这个内存地址。
下面是个示意表格。
语句 | 变量 | 值 | Get | 访问类型 |
---|---|---|---|---|
var a = 1 |
a | 1 |
1 | 按值 |
var a = [] |
a | 0x00000320 |
[] |
按引用 |
抬杠
Undefinded, Null, Boolean, Number
是基本类型可以理解,因为这些类型的变量所占用的内存空间都是大小固定的。但是string
类型的变量,字符串的长短都是不一样的,也就是说,字符串占用的内存空间大小是不固定的,为什么string被列为按值访问呢?
基本类型和引用类型的本质区别是,当这个变量被分配
值时,它需要向操作系统申请内存资源,如果你向操作系统申请的内存空间的大小是固定的,那么就是基本类型,反之,则为引用类型。
5. 例子的解释
var var1 = 1
var var2 = true
var var3 = [1,2,3]
var var4 = var3
function test (var1, var3) {
var1 = 'changed' // a
var3[0] = 'changed' // b
var3 = 'changed' // c
}
test(var1, var3)
console.log(var1, var2, var3, var4)
上面的js分为两个调用栈,在
- 图1 外层的调用栈。有四个变量v1、v2、v3、v4
- 图2 调用test是传参,内层的v1、v3会屏蔽外层的v1、v3。内层的v1,v3和外层的v1、v3内存地址是不同的。内层v1和外层v1已经没有任何关系了,但是内层的v3和外层v3仍然指向同一个数组。
- 图3 内层的v1的值被改变成'changed‘, v3[0]的值被改变为'changed'。
- 图4 内层v3的值被重写为字符串
changed
, 彻底断了与外层v3联系。 - 图5 当test执行完毕,内层的v1和v3将不会存在,ox75和ox76位置的内存空间也会被释放
最终的输出:
1 true ["changed", 2, 3] ["changed", 2, 3]
6. 如何深入学习JS、Node.js
看完两个stackoverflow上两个按照投票数量的榜单
如果学习有捷径的话,踩一遍别人踩过的坑,可能就是捷径。
7. 参考
- is-javascript-a-pass-by-reference-or-pass-by-value-language
- Is number in JavaScript immutable? duplicate
- Immutability in JavaScript
- the-secret-life-of-javascript-primitives
- JavaScript data types and data structuresLanguages Edit Advanced
- Understanding Javascript immutable variable
- Explaining Value vs. Reference in Javascript
- You-Dont-Know-JS
- 《JavaScript高级程序设计(第3版)》[美] 尼古拉斯·泽卡斯
来源:https://segmentfault.com/a/1190000017407403
深入理解 JavaScript中的变量、值、传参的更多相关文章
- 浅显易懂的理解JavaScript中的this关键字
在JavaScript中this变量是一个令人难以摸清的关键字,this可谓是非常强大,充分了解this的相关知识有助于我们在编写面向对象的JavaScript程序时能够游刃有余. 1. 一般用处 对 ...
- 深入理解JavaScript中创建对象模式的演变(原型)
深入理解JavaScript中创建对象模式的演变(原型) 创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Objec ...
- 深入理解JavaScript中的属性和特性
深入理解JavaScript中的属性和特性 JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性. 主要内容如下: 理解JavaSc ...
- 深入理解javascript中的立即执行函数(function(){…})()
投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-06-12 我要评论 这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是 ...
- 全面理解JavaScript中的 this
全面理解JavaScript中的 this 上下文 VS 作用域 作用域(scope) 是在运行时代码中的某些特定部分中变量,函数和对象的可访问性.换句话 说,作用域决定了代码区块中变量和其他资源的可 ...
- 【拾遗】理解Javascript中的Arguments
前言 最近在看JavaScript相关的知识点,看到了老外的一本Javascript For Web Developers,遇到了一个知识盲点,觉得老外写的很明白很透彻,记录下来加深印象,下面是我摘出 ...
- 理解javascript中的回调函数(callback)【转】
在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Object类的对象一样用于内置对象的管理.因为function实 ...
- 深入理解javascript中的立即执行函数
这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包住业务代码,使用jquery时比较常见,需要的朋友可以 ...
- 深入理解JavaScript中的作用域和上下文
介绍 JavaScript中有一个被称为作用域(Scope)的特性.虽然对于许多新手开发者来说,作用域的概念并不是很容易理解,我会尽我所能用最简单的方式来解释作用域.理解作用域将使你的代码脱颖而出,减 ...
随机推荐
- 8. ClustrixDB 监控
一. 列出集群中当前会话 sql> select * from system.sessions\G 二. 显示CPU利用率.磁盘读/写利用率和缓冲区缓存失误率 MySQL [system]> ...
- luogu P1077 摆花 x
P1077 摆花 题目描述 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆.通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号.为了在门口展出更多种花,规定第i种花不能 ...
- python安装报错error writing to file:......
今天换了win10 64电脑,安装python3.6.8时,报错:error writing to file:...... 安装时,右键--以管理员身份运行,安装成功.
- Eating Plan
Eating Plan 2019南昌G 模数为合数,所以只有约3000个数字不为0 记录一下不为0的数字位置 H[x]代表距离为x的连续段的数字和的最大值 处理出H[x] 再H[x] = max(H[ ...
- 把一个树莓派SD卡系统和文件迁移到空SD卡中
1.打开win32diskimager软件读出SD卡树莓派系统和文件到电脑的镜像文件中, 2.使用 SD card formatter 格式化SD卡 3.再用win32diskimager往空SD卡写 ...
- spring boot中使用ehcache
1在启动类上使用注解 @SpringBootApplication @EnableCaching public class ConfApplication { ...... } 2在resources ...
- git reset --hard 操作后的数据恢复
在进行正文之前先简单介绍下git reset 命令 git reset git reset 命令用于改变当前的仓库状态,简单的场景用例:假设一次修改了两个文件,然而需要对这两个文件分别进行两次提交,在 ...
- java jar 服务自启动存在的坑及解决办法
为了在服务器重启的时候,java程序能够自动重启,我们通常把它加到服务里面 ln -s /full/path/to/jar /etc/init.d/service_name # start servi ...
- 基于球分割的空间二叉树检索算法(sphere-kdtree)
sphere-kdtree算法思路说明 具体思路如下: 第一.球半径分割,即利用不同的球半径,将三维空间点(向量)分割成多块.所以首先要求确定的就是分割多少块,怎么设置半径最合理. 第二.三维空间点平 ...
- C/C++判断字符串是否包含某个字符串
C风格 #include <iostream> #include <string> #include <cstring> using namespace std; ...