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. 变量访问有哪些方式?

变量访问的方式有两种:

  1. 按值访问
  2. 按引用访问

在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. 参考

来源:https://segmentfault.com/a/1190000017407403

深入理解 JavaScript中的变量、值、传参的更多相关文章

  1. 浅显易懂的理解JavaScript中的this关键字

    在JavaScript中this变量是一个令人难以摸清的关键字,this可谓是非常强大,充分了解this的相关知识有助于我们在编写面向对象的JavaScript程序时能够游刃有余. 1. 一般用处 对 ...

  2. 深入理解JavaScript中创建对象模式的演变(原型)

    深入理解JavaScript中创建对象模式的演变(原型) 创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Objec ...

  3. 深入理解JavaScript中的属性和特性

    深入理解JavaScript中的属性和特性 JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性. 主要内容如下: 理解JavaSc ...

  4. 深入理解javascript中的立即执行函数(function(){…})()

    投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-06-12 我要评论 这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是 ...

  5. 全面理解JavaScript中的 this

    全面理解JavaScript中的 this 上下文 VS 作用域 作用域(scope) 是在运行时代码中的某些特定部分中变量,函数和对象的可访问性.换句话 说,作用域决定了代码区块中变量和其他资源的可 ...

  6. 【拾遗】理解Javascript中的Arguments

    前言 最近在看JavaScript相关的知识点,看到了老外的一本Javascript For Web Developers,遇到了一个知识盲点,觉得老外写的很明白很透彻,记录下来加深印象,下面是我摘出 ...

  7. 理解javascript中的回调函数(callback)【转】

    在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Object类的对象一样用于内置对象的管理.因为function实 ...

  8. 深入理解javascript中的立即执行函数

    这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包住业务代码,使用jquery时比较常见,需要的朋友可以 ...

  9. 深入理解JavaScript中的作用域和上下文

    介绍 JavaScript中有一个被称为作用域(Scope)的特性.虽然对于许多新手开发者来说,作用域的概念并不是很容易理解,我会尽我所能用最简单的方式来解释作用域.理解作用域将使你的代码脱颖而出,减 ...

随机推荐

  1. 在postman中请求的接口有csrf怎么办

    今天在写项目的时候,写了一个post接口,为了防止crsf攻击,config.defalut.js文件中加了如下代码: exports.security = { csrf: { ignoreJSON: ...

  2. 消息队列之--Kafak

    序言 消息丢失如何解决? 解耦 异步 并行 Docker安装Kafak 1.下载镜像 # zookeeper镜像 docker pull wurstmeister/zookeeper # kafka镜 ...

  3. iview2.0 日期选择器DatePicker 所选时间格式不对

    网上有很多解决方式,大部分都是加个@on-change事件.比如下图: 但是如果是编辑的时候,打开编辑页面,通过数据库返回时间显示出来是对的,但是不触发change事件,直接点保存的话,保存后还是少8 ...

  4. BZOJ 4011: [HNOI2015]落忆枫音 计数 + 拓扑排序

    Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出 这样一个问题.  「相信吧.不然我们是什么,一团肉吗?要不是有灵魂……我们 ...

  5. Codeforces Gym 100851 K King's Inspection ( 哈密顿回路 && 模拟 )

    题目链接 题意 : 给出 N 个点(最多 1e6 )和 M 条边 (最多 N + 20 条 )要你输出一条从 1 开始回到 1 的哈密顿回路路径,不存在则输出 " There is no r ...

  6. 【BZOJ4565】 [Haoi2016]字符合并

    Description 有一个长度为 n 的 01 串,你可以每次将相邻的 k 个字符合并,得到一个新的字符并获得一定分数.得到的新字 符和分数由这 k 个字符确定.你需要求出你能获得的最大分数. I ...

  7. 容器适配器————stack

    只能访问 stack 顶部的元素:只有在移除 stack 顶部的元素后,才能访问下方的元素. 堆栈操作 top():返回一个栈顶元素的引用,类型为 T&.如果栈为空,返回值未定义. push( ...

  8. Ubuntu18.04修改为阿里云

    对源安装时,要先知道系统的版本,以免安装错的版本 使用命令:lsb_release -c 备份原先的配置文件 cd /etc/apt sudo cp sources.list sources.list ...

  9. sourcetree pull push需要密码问题

    我的是mac,以mac版本的sourcetree 为例 第一步 项目仓库右上角设置 第二步.点击远程仓库.  点击仓库路径点击编辑 第三步  url/路径修改 原本.https://gitee.com ...

  10. 安装telnet服务

    一.安装telnet1.检测telnet-server的rpm包是否安装 [root@localhost ~]# rpm -qa telnet-server 若无输入内容,则表示没有安装.出于安全考虑 ...