引言

JavaScript的变量本质是松散类型的,也就是说其变量就是用于保存特定值的一个名字,变量的值和数据类型可以在脚本执行的生命周期中发生变化。这是一个很有趣很强大的特性,但是也是一个极容易出错误的地方。

两大类型

基本类型:指的是简单的数据段,有五种基本类型:Undefined,Null,Boolean,Number,String。这几种基本类型是按值访问的,操作变量时操作的是保存在变量中实际的值。

引用类型:指哪些可能由多个值构成的对象(Object)。引用类型的值是保存在内存中的对象。需要注意的是,JavaScript不允许直接访问内存中的位置,所以操作对象时,实际是操作对象的引用(这种说法是不严谨的,因为当复制保存对象的变量时,操作的是对象的引用;但是在为对象添加属性时,操作的是对象实际本身)。

变量的复制

基本类型变量的复制

当复制基本类型的变量时,实际是在变量对象上创建一个新值,然后把这个创建的新值分配给为新变量复制的位置上。所以原始变量和被赋值的变量在内存中是独立的,这两个变量可以参与任意操作而不会相互影响

var a = 'test';
var b = a;
a = 'change';
console.log(b);
//输出:test

 

引用类型变量的复制

当复制引用变量的值时,也是讲存储在变量对象中的值复制一份放在新变分配的空间中。但是这里需要理解的是,这个值的副本实际是一个指针,而这个指针指向存储在堆内存中的一个对象。上面已经说过了:对于引用类型的变量,JavaScript不允许直接操作对象,而是操作对象的引用,所以在引用变量中存储的是一个指向实际存储空间的指针。复制结束后两个变量实际引用的一个对象,所以改变其中一个变量,另一个将会受到影响。

var a = new Object();
var b = a;
a.title = 'test';
console.log(b.title);
//输出:test

保存在变量对象中的变量和保存在堆中的对象之间的关系(不要在意图片丑~)

参数传递

在ECMAScript中所有函数的参数都是按值传递的。什么意思呢?就是把函数体外面的值复制给函数内部的参数(如同把值从一个变量复制到另一个变量一样)。这样子就很好理解了。和理解了上面变量的复制,也就很好理解js中参数的传递特性了。

在向参数传递基本类型值时,被传递的值会被赋值给一个局部变量,即函数体的命名参数(在ECMAScript中就是arguments对象中的一个元素)。在向参数传递引用类型的值时,会把这个值在内存中的地址赋值给参数。

function setName(n) {
n = 'test';
return n;
}
var a = 'haha';
var b = setName(a);
console.log(a);
console.log(b);
//输出:
//haha
//test

如果使用引用类型作为参数:

function setName(obj) {
obj.name = 'shanlei';
}
var a = new Object();
setName(a);
console.log(a.name);
//输出:shanlei

在这个函数中obj和a引用的是同一个对象,挡在setName中添加name属性后,函数外部也会有所反应。在这里有人可能会错误的认为在局部作用域中修改的对象会在全局作用域中反映出来,就是说明这个参数是按引用传递的。这个思想是错误的。可以看下面这个例子:

function setName(obj) {
obj.name = 'shanlei';
obj = new Object();
obj.name = 'Grep';
}
var a = new Object();
setName(a);
console.log(a.name);
//输出:shanlei

在这段中,我们将obj重新定义了一个对象,并且给这个新对象定义一个不同值的name属性。如果参数是按引用传递的,那么a应该会自动被修改为指向其name属性设置为'Grep'的新对象。因为如果参数是以引用传递的,那么obj和a应该是统一引用,这个引用指向堆中实际存储对象的空间。当生成一个新的对象设置新的name属性并将这个新对象给obj时,实际上就是改变了这个引用在堆中的指向,所以外部的a也就会自动改变。而输出的依旧是'shanlei',这说明在函数内部修改了参数的值,但原始的引用依旧没有改变。因为obj和a在内存中是两个独立的变量对象,这两个变量对象指向堆中同一空间,当生成新对象并传递给obj时,obj的指向发生改变,但是a的指向依旧是堆中原始的空间,所以输出的依旧是‘shanlei’。当在函数内部重写obj时,这个变量引用就是一个局部对象,且这个局部对象在函数执行完毕以后会立即销毁。

以上~~

JavaScript变量那些事的更多相关文章

  1. javascript变量的作用域

    javascript变量的作用域 基本类型和引用类型 基本类型值指的是简单的数据段,而引用类型值指的是那个可能由多个值组成的对象  讲一个值赋值给变量时,javascript解析器首先要确定是基本类型 ...

  2. JavaScript 变量声明提前

    <JavaScript权威指南>中指出:JavaScript变量在声明之前已经可用,JavaScript的这个特性被非正式的称为声明提前(hoisting),即JavaScript函数中声 ...

  3. JavaScript 变量

    一,JavaScript 变量(存储信息的容器) 与代数一样,JavaScript 变量可用于存放值(比如 x=2)和表达式(比如 z=x+y). 变量可以使用短名称(比如 x 和 y),也可以使用描 ...

  4. javascript变量声明 及作用域

    javascript变量声明提升(hoisting) http://openwares.net/js/javascript_declaration_hoisting.html 可能要FQ一下 java ...

  5. JavaScript 变量作用域

    一. 变量声明 变量用var关键字来声明,如下所示: 变量在未声明的情况下被初始化,会被添加到全局环境. JavaScript执行代码时,会创建一个上下文执行环境,全局环境是最外围的环境.每个函数在被 ...

  6. 【转】javascript变量声明 及作用域

    javascript变量声明提升(hoisting) javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 先看 ...

  7. JavaScript变量和数据类型

    变量 变量就是一个元素,类似于数学中的概念,用来指定表示一个对象.在JavaScript中,用来指定变量的关键字为var.当声明新变量时,可以使用关键词 "new" 来声明其类型 ...

  8. 回归基础: JavaScript 变量提升

    from me: javascript的变量声明具有hoisting机制,它是JavaScript一个基础的知识点,也是一个比较容易犯错的点,平时在开发中,大大小小的项目都会遇到. 它是JavaScr ...

  9. JavaScript - 变量,作用域,内存

    JavaScript 变量可以用来保存两种类型的值:基本类型值和应用类型值.基本类型的值源自以下5种基本数据类型:Undefined.Null.Bollean.Number和String. 所有变量都 ...

随机推荐

  1. Multithreading in C

    Multithreading in C, POSIX(可移植操作系统接口Portable Operating System Interface X ) style Multithreading - A ...

  2. <<高级计算机网络>>(Advaned Computer Networks) 徐恪 徐明伟 陈文龙 马东超

    目录 第1章 计算机网络与Internet1 1.1 引言1 1.2 Internet发展历史2 1.2.1 互联网发展的主要阶段4 1.2.2 互联网在中国的发展5 1.2.3 互联网主要创新5 1 ...

  3. 训练超参数, 出现 Cannot use GPU in CPU-only Caffe 错误?

    当我们用MNIST手写体数字数据库和LeNet CNN 模型训练超参数,运行 examples/mnist/train_lenet.sh是出现Cannot use GPU in CPU-only Ca ...

  4. ESXi系统命令行下启动虚拟机

    从命令行启动虚拟机: 用命令列出虚拟机的ID:vim-cmd vmsvc/getallvms |grep <vm name>注意: 第一列输出是vmid. 用命令查看虚拟机启动状态:vim ...

  5. Caffe 议事(一):从零开始搭建 ResNet 之 残差网络结构介绍和数据准备

    声明:Caffe 系列文章是我们实验室 黄佳斌 大神所写的内部学习文档,已经获得他的授权允许. 本参考资料是在 Ubuntu14.04 版本下进行,并且默认 Caffe 所需的环境已经配置好,下面教大 ...

  6. LDA详解

    PART 1 这个性质被叫做共轭性.共轭先验使得后验概率分布的函数形式与先验概率相同,因此使得贝叶斯分析得到了极⼤的简化.   V:文档集中不重复的词汇的数目 语料库共有m篇文档,: 对于文档,由个词 ...

  7. Word直接发布新浪博客(以Word 2010为例)

    目前大部分的博客作者在用Word写博客这件事情上都会遇到以下3个痛点: 1.所有博客平台关闭了文档发布接口,用户无法使用Word,Windows Live Writer等工具来发布博客.使用Word写 ...

  8. VS2017设置默认管理员权限启动

    找到vs安装目录下的:C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\devenv.exe 右键- ...

  9. Duplicate Symbol链接错误的原因总结和解决方法[转]

    from:http://www.cocoachina.com/bbs/read.php?tid=177492 duplicate symbol是一种常见的链接错误,不像编译错误那样可以直接定位到问题的 ...

  10. 团体程序设计天梯赛L1-018 大笨钟 2017-03-22 17:29 79人阅读 评论(0) 收藏

    L1-018. 大笨钟 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 微博上有个自称"大笨钟V"的家伙,每 ...