深入解析js中基本数据类型与引用类型,函数参数传递的区别
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中基本数据类型与引用类型,函数参数传递的区别的更多相关文章
- JS中基本数据类型和引用类型最根本的区别
栈内存和堆内存:https://segmentfault.com/a/1190000015118062 https://segmentfault.com/a/1190000016389376 变量:内 ...
- 浅解析js中的对象
浅解析js中的对象 原文网址:http://www.cnblogs.com/foodoir/p/5971686.html,转载请注明出处. 前面的话: 说到对象,我首先想到的是每到过年过节见长辈的时候 ...
- js中的数据类型
JS中的数据类型: ——数字 (number)NaN ——字符串(string) ——布尔 (boolean)——函数 (function) 也是对象的一种 ——对象 (object) ...
- JS中的数据类型和转换
一.JS中的数据类型 js中的数据类型可以分为五种:number .string .boolean. underfine .null. number:数字类型 ,整型浮点型都包括. string:字符 ...
- js中的数据类型、以及浅拷贝和深拷贝
一.js中的数据类型 1.基本类型(值类型):Undefined.Boolean.String.Number.Symbol 2.引用类型:函数.数组.对象.null.new Number(10)都是对 ...
- Javascript高级编程学习笔记(3)—— JS中的数据类型(1)
前一段时间由于事情比较多,所以笔记耽搁了一段时间,从这一篇开始我会尽快写完这个系列. 文章中有什么不足之处,还望各位大佬指出. JS中的数据类型 上一篇中我写了有关JS引入的Script标签相关的东西 ...
- JS中判断数据类型的几种方法
1⃣️首先我们来了解一下js中的数据类型 1.基本数据类型:Undefined.Null.Boolean.Number.String(值类型) 2.复杂数据类型:Object(引用类型) (值类型和引 ...
- 如何判断js中的数据类型?
js六大数据类型:number.string.object.Boolean.null.undefined string: 由单引号或双引号来说明,如"string" number: ...
- 如何判断js中的数据类型
如何判断js中的数据类型:typeof.instanceof. constructor. prototype方法比较 如何判断js中的类型呢,先举几个例子: var a = "iamstri ...
随机推荐
- SpringMVC 用http请求的Get和Post请求作为路由的方法的重载方式
@Controller @RequestMapping("/messageProcessing") public class WechatPushController { @Aut ...
- Python 基礎 - 數據類型
標準數據類型 Python3 中有六個標準的數據類型 1 Number(數字) 2 String(字符串) 3 List (列表) 4 Tuple (元組) 5 Sets (集合) 6 Diction ...
- raw_input 和input的区别
input它会根据用户输入变换相应的类型, raw_input则是不管用户输入什么类型的都会转变成字符型.
- LintCode Binary Tree Preorder Traversal
Given a binary tree, return the preorder traversal of its nodes' values. Given: 1 / \ 2 3 / \ 4 5 re ...
- 如何在JBoss WildFly 8 自定义log4j日志
最近在 JBoss WildFly 8 下部署 Web应用,自定义的 log4j 日志不工作.console下无日志输出,用System.out.println都不输出内容到console. 原因是J ...
- strncpy基本用法
见百度百科. 注意这句话: (c/c++)复制src中的内容(字符,数字.汉字....)到dest,复制多少由num的值决定,返回指向dest的指针.如果遇到null字符('\0'),且还没有到num ...
- hdu4671 Backup Plan ——构造题
link:http://acm.hdu.edu.cn/showproblem.php?pid=4671 其实是不难的那种构造题,先排第一列,第二列从后往前选. #include <iostrea ...
- linux crontab -r 导致no crontab for root的原因及解决方案
使用方式 : crontab file [-u user]-用指定的文件替代目前的crontab. crontab-[-u user]-用标准输入替代目前的crontab. crontab-1[use ...
- HDU 2577(DP)
题意:要求一个字符串输入,按键盘的最少次数.有Caps Lock和Shift两种转换大小写输入的方式 思路:用dpa与dpb数组分别记录Caps Lock的开关状态,dpa表示不开,dpb表示开 代码 ...
- JSP知识点汇总
有几种方法可以实现服务器内部跳转? 使用request对象提供的方法:request.getRequestDispatcher(String URI).forward(ServletRequest r ...