资讯专栏INFORMATION COLUMN

深入理解 JavaScript中的变量、值、传参

endiat / 1613人阅读

摘要:所以说在中,也并不是一切都是对象原始类型值不可变原始类型的变量的值是不可变的,只能给变量赋予新的值。可以理解基本类型的变量的值,就是字面上写的数值。有四个变量图调用是传参,内层的会屏蔽外层的。图内层的的值被改变成的值被改变为。

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 基本包装类型。

所以说:在js中,也并不是一切都是对象

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上两个按照投票数量的榜单

JavaScript问题榜单

Node.js问题榜单

如果学习有捷径的话,踩一遍别人踩过的坑,可能就是捷径。

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://www.ucloud.cn/yun/100122.html

相关文章

  • 关于JavaScript 函数传参

    摘要:最早由在年的语言中提出。该求值策略被用于等多种语言。该策略的重点是调用函数传参时,函数接受对象实参引用的副本既不是按值传递的对象副本,也不是按引用传递的隐式引用。它和按引用传递的不同在于在共享传递中对函数形参的赋值,不会影响实参的值。 周五晚上下班回家的路上,突然想到了 CommonJS 规范、Node.js 模块化等等各种东西,然后就想到了熟悉的 module.exports。 大约...

    CloudwiseAPM 评论0 收藏0
  • 图解JavaScript的参数传递

    摘要:写在最前本次尝试通过流程图的形式并结合两个例子来重新理解一下中的参数传递。欢迎关注我的博客,不定期更新中参数到底如何传递借用红宝书的一句话中所有函数的参数都是按值传递的这个值如果是简单类型,那么就是其本身。同时执行第一个结果即为。 写在最前 本次尝试通过流程图的形式并结合两个例子来重新理解一下JavaScript中的参数传递。 欢迎关注我的博客,不定期更新中—— 参数到底如何传递? 借...

    Berwin 评论0 收藏0
  • call by sharing——JavaScript中“共享传参”和“按传参”的理解

    摘要:众所周知,中参数是按值传递的。先大概介绍按值传参基本类型基本类型的参数传递比较简单,示例代码的值复制给了函数内部的局部变量所以在函数内部改变的值并不会影响外部的值。 众所周知,JavaScript中参数是按值传递的。与访问变量不同,基本类型和引用类型的参数在传递时都如同变量的复制。 但是我们在使用引用类型的参数传递时,经常会发现在函数内改变引用类型参数(如对象)会在函数外反映出来,这种...

    jsdt 评论0 收藏0
  • 深入理解ES6》笔记——函数(3)

    摘要:错误的写法错误的写法中的构造函数新增了支持默认参数和不定参数。箭头函数的简单理解箭头函数的左边表示输入的参数,右边表示输出的结果。但是有了尾调用优化之后,递归函数的性能有了提升。 作为前端切图仔,越发觉得自己离不开函数了。 说到JavaScript函数,脑子里都是匿名函数、普通函数、闭包函数、构造函数......然后还能说出一大堆函数的概念。如果你达到这个水平,那么函数对你来说没有难度...

    DoINsiSt 评论0 收藏0

发表评论

0条评论

endiat

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<