ECMAScript的数据有两种类型:基本类型值和引用类型值,基本类型指的是简单的数据段,引用类型指的是可能由多个值构成的对象。

Undefined、Null、Boolean、Number和String是值类型,其他都是引用类型。其他语言String是以对象的形式表示,ECMAScript放弃了这一传统。

内存中的存储区域

值类型存储在栈中,引用类型存储在堆中。内存中是分为两个区域的,一个是栈:它就是专门存放值类型的,但是它有一定的存储空间,只能存放基本数据类型的数据和对象类型的引用地址也叫哈希码。存储在栈里面的基本数据类型的值都是有最大值和最小值的,不能超出它的默认范围;二就是堆:它的存储空间大,是用来存储“数组类型”和“对象类”的数据的。存储在堆里的引用类型数据是没有固定大小的,比如说一个对象类型的数据,你可以往里面存放一个字符、两个字符·····更多,不管你存多少它都会把你存放的数据在内存的堆里面开辟一块空间来存储,在栈里面开辟一块空间来存放引用地址,栈是后进先出的。

复制变量值

  • 复制基本类型值

    会在上重新分配一个内存空间,来存当前赋值的变量,这两个变量可以参与任何操作而不会相互影响。
var name1 = 'kenny';
var name2 = name1;
name2 // 'kenny'
name2 = 'wukongyun';
name1 //'kenny'
  • 复制引用类型值

将存储在变量对象中的值复制一份放到新变量分配的空间中(新变量的指针存储在栈上),复制的实际上是一个指针,而这个指针指向存储在堆中的一个对象。两个变量实际上引用的是同一个对象。改变其中一个变量,就会影响另一个变量。

var obj1 = {name: 'kenny'};
var obj2 = obj1;
obj1.name = 'kongyun';
obj2.name // 'kongyun'

参数的传递

ECMAScript所有的函数的参数都是按值传递的。函数外部的值赋值给函数内部的参数,与一个变量复制到另一个变量一样。基本类型值的传递和基本类型一样,引用类型的传递和引用类型的复制一样。

function addTen(num) {
num +=10;
return num;
}
var count = 20;
var result = addTen(count);
console.log(count); //20没有变化
console.log(result);// 30

引用类型也是按值传递

function setName(obj) {
obj.name = 'kenny';
obj = new Object();
obj.name = 'kongyun';
} var person = new Object();
setName(person);
console.log(person.name); // 'kenny'

即使在函数内部修改了参数的值,但原始的引用(person对象,存储在堆上)仍保持不变。具体传递的obj不是指针而是指针引用的对象(副本copy)。实际上,当在函数内部重写obj时,这个变量的引用的就是一个局部对象了,而这个局部对象会在函数执行完毕后立即被销毁。

类似于这种例子 - -

var a = [1, 2];
var b = a;
a = {a:1, b:2};//虽然a改变了,但是b依然没变,值传递,复制了个指针

扩展:值传递与引用传递

  • 值传递:call by value
  • 引用传递:call by Call by reference

值传递和引用传递,属于函数调用时参数的求值策略(Evaluation Strategy),这是对调用函数时,求值和传值的方式的描述,而非传递的内容的类型(内容指:是值类型还是引用类型,是值还是指针)。值类型/引用类型,是用于区分两种内存分配方式,值类型在调用栈上分配,引用类型在堆上分配。一个描述内存分配方式,一个描述参数求值策略,两者之间无任何依赖或约束关系。

区别 值传递 引用传递
根本区别 会创建副本(copy) 不创建副本
所以 函数中无法改变原始对象 函数中可以改变原始对象

对于值传递,无论是值类型还是引用类型,都会在调用栈上创建一个副本,不同是,对于值类型而言,这个副本就是整个原始值的复制。而对于引用类型而言,由于引用类型的实例在堆中,在栈上只有它的一个引用(一般情况下是指针),其副本也只是这个引用的复制,而不是整个原始对象的复制。

这便引出了值类型和引用类型(这不是在说值传递)的最大区别:值类型用做参数会被复制,但是很多人误以为这个区别是值类型的特性。其实这是值传递带来的效果,和值类型本身没有关系。只是最终结果是这样。

深入解析js中基本数据类型与引用类型,函数参数传递的区别的更多相关文章

  1. JS中基本数据类型和引用类型最根本的区别

    栈内存和堆内存:https://segmentfault.com/a/1190000015118062 https://segmentfault.com/a/1190000016389376 变量:内 ...

  2. 浅解析js中的对象

    浅解析js中的对象 原文网址:http://www.cnblogs.com/foodoir/p/5971686.html,转载请注明出处. 前面的话: 说到对象,我首先想到的是每到过年过节见长辈的时候 ...

  3. js中的数据类型

    JS中的数据类型: ——数字  (number)NaN ——字符串(string) ——布尔  (boolean)——函数  (function)     也是对象的一种 ——对象  (object) ...

  4. JS中的数据类型和转换

    一.JS中的数据类型 js中的数据类型可以分为五种:number .string .boolean. underfine .null. number:数字类型 ,整型浮点型都包括. string:字符 ...

  5. js中的数据类型、以及浅拷贝和深拷贝

    一.js中的数据类型 1.基本类型(值类型):Undefined.Boolean.String.Number.Symbol 2.引用类型:函数.数组.对象.null.new Number(10)都是对 ...

  6. Javascript高级编程学习笔记(3)—— JS中的数据类型(1)

    前一段时间由于事情比较多,所以笔记耽搁了一段时间,从这一篇开始我会尽快写完这个系列. 文章中有什么不足之处,还望各位大佬指出. JS中的数据类型 上一篇中我写了有关JS引入的Script标签相关的东西 ...

  7. JS中判断数据类型的几种方法

    1⃣️首先我们来了解一下js中的数据类型 1.基本数据类型:Undefined.Null.Boolean.Number.String(值类型) 2.复杂数据类型:Object(引用类型) (值类型和引 ...

  8. 如何判断js中的数据类型?

    js六大数据类型:number.string.object.Boolean.null.undefined string: 由单引号或双引号来说明,如"string" number: ...

  9. 如何判断js中的数据类型

    如何判断js中的数据类型:typeof.instanceof. constructor. prototype方法比较 如何判断js中的类型呢,先举几个例子: var a = "iamstri ...

随机推荐

  1. php大力力 [043节] 现在要做个删除前的提示功能

    php大力力 [043节] 现在要做个删除前的提示功能

  2. Structs2中iterator的status属性的用法

    iterator标签主要是用于迭代输出集合元素,如list set map 数组等,在使用<s:iterator/>标签的时候有三个属性值得我们关注 1. value属性:可选的属性,va ...

  3. Insert Interval

    在已经排好序的区间中,插入一个新的区间,与merge的做法类似 Given a set of non-overlapping intervals, insert a new interval into ...

  4. Ubuntu 14.04下安装Hadoop2.4.0 (单机模式)

    转自 http://www.linuxidc.com/Linux/2015-01/112370.htm 一.在Ubuntu下创建Hadoop组和hadoop用户 增加hadoop用户组,同时在该组里增 ...

  5. SEL方法选择器

    在Objective-C中,选择器(selector)有两个意思. 一是指在代码中的方法的名称.二是指在编译是用于替换方法名称的唯一的标识符.编译后的选择器的为SEL类型.所有名称相同的方法拥有同一个 ...

  6. Objective-c——UI基础开发第十天(自动布局)

    一.autoresizing 的使用(了解) 只能参照父控件 1.实现横竖屏幕切换,不能把控件的frame血丝,需要进行屏幕适配 2.需要参照父控件 use auto layout禁用 才会出现aut ...

  7. POJ 3321 Apple Tree(树状数组)

                                                              Apple Tree Time Limit: 2000MS   Memory Lim ...

  8. myeclipse启动tomcat报错cannot find a free socket for debugger

    解决办法,命令行输入netsh winsock reset,winsock是Windows网络编程接口,winsock工作在应用层,它提供与底层传输协议无关的高层数据传输编程接口 netsh wins ...

  9. Deleting backup_label on restore will corrupt your database!

    The quick summary of this issue is that the backup_label file is an integral part of your database c ...

  10. python笔记集合

    1.win_64下编译pyd(编译器用的tdm-gcc-5.1) gcc test.c -shared -Ic:\Python27\include -Lc:\Python27\libs -lpytho ...