摘要:js的数据类型有种划分方式为 原始数据类型和 引用数据类型。

原始数据类型 存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。栈区包括了 变量的标识符和变量的值。

引用数据类型 存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。放在栈空间中的值是该对象存储在堆中的地址。

按值传递 VS. 按引用传递

按值传递(call by value)是最常用的求值策略:函数的形参是被调用时所传实参的副本。修改形参的值并不会影响实参。

按引用传递(call by reference)时,函数的形参接收实参的隐式引用,而不再是副本。这意味着函数形参的值如果被修改,实参也会被修改。同时两者指向相同的值。

按引用传递会使函数调用的追踪更加困难,有时也会引起一些微妙的BUG。

按值传递由于每次都需要克隆副本,对一些复杂类型,性能较低。两种传值方式都有各自的问题。

demo实例

typeof 运算符,返回一个字符串,指示未计算的操作数的类型

    var person,name;
person = 'kn'; name=person;
person='黑白';
console.log(person,name,typeof person)//黑白 kn string

person的改变没有改变name,说明 string 是按值传递的。赋值时创建一块新的内存空间

1、基本类型

  • Boolean.  布尔值,true 和 false.
  • null. 一个表明 null 值的特殊关键字。 JavaScript 是大小写敏感的,因此 null 与 NullNULL或其他变量完全不同。
  • undefined.  变量未定义时的属性。
  • Number.  表示数字,例如: 42 或者 3.14159。
  • String.  表示字符串,例如:"Howdy"
  • Symbol ( 在 ECMAScript 6 中新添加的类型).。一种数据类型,它的实例是唯一且不可改变的。

不可变(immutable)性质

基本类型是不可变的(immutable),只有对象是可变的(mutable). 有时我们会尝试“改变”字符串的内容,但在JS中,任何看似对string值的”修改”操作,实际都是创建新的string值。任何方法都无法改变一个基本类型的值,

     var str = "abc";
str[0]; // "a"
str[0] = "d";
console.log(str); //abc var name = 'jozo';
var upName=name.toUpperCase();
console.log(upName,name); // 输出 'JOZO' 'jozo'

方法操作无法改变一个基本类型的值

     var person = 'kn';
person.age = 24;
person.method = function(){}; console.log(person.age); // undefined
console.log(person.method); // undefined

上面代码可知,我们不能给基本类型添加属性和方法

2.引用类型

引用类型的值是可变的


     var obj = {x : 0};
obj.x = 100;
var o = obj;
o.x = 1;
console.log(obj.x)// 1, 被修改
o = {x:100}; //等同于重新赋值,重新开辟内存,不是修改
console.log(JSON.stringify(obj),JSON.stringify(o))//{"x":1} {"x":100}
obj.x; // 1, 不会因o = {"x":100}改变

引用类型的值是同时保存在栈内存和堆内存中的对象

javascript和其他语言不同,其不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间,那我们操作啥呢? 实际上,是操作对象的引用,
所以引用类型的值是按引用访问的。
准确地说,引用类型的存储需要内存的栈区和堆区(堆区是指内存里的堆内存)共同完成,栈区内存保存变量标识符和指向堆内存中该对象的指针,
也可以说是该对象在堆内存的地址。
假如有以下几个对象:

var person1 = {name:'jozo'};
var person2 = {name:'xiaom'};
var person3 = {name:'xiaoq'};

则这三个对象的在内存中保存的情况如下图:

    var person1 = {};
var person2 = {};
console.log(person1 == person2); // false

引用类型时按引用访问的,换句话说就是比较两个对象的堆内存中的地址是否相同,那很明显,person1和person2在堆内存中地址是不同的。

两种数据类型在实参和形参中的区别

首先要明白什么实参什么是形参。

实参:可以是常量、变量、表达式、函数等, 无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值, 以便把这些值传送给形参。 因此应预先用赋值,输入等办法使实参获得确定值。
形参:全称为“形式参数”是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传递的参数。
形参的作用是实现主调函数与被调函数之间的联系,通常将函数所处理的数据,影响函数功能的因素或者函数处理的结果作为形参。
function addNum(param)  //相对于addNum方法来说 param是形参
{
param+=10;
  return param;
}
var num=10;
var result=addNum(num); //相对于addNum方法来说 num是实参
console.log(num); //10
console.log(result);//

上面的例子中,当将 num作为实参传入方法 addNum是 param作为形参接受 并在方法体内使用,且num在全局中没用改变,但当实参为引用类型时

 function fun(param)  //相对于fun方法来说 param是形参
{
param[0]=99;
  return param;
}
var num=[10];
var result=fun(num); //相对于fun方法来说 num是实参
console.log(num[0]); //99
console.log(result);//[99]

在方法体内改变 形参将同时改变实参。这个是其他语言中不会存在的,例如php,需要操作引用时,使用 &地址符 在形参的时候声明

 <?php
function fun($param) //相对于fun方法来说 param是形参 function fun(&$param){}
{
$param[0]=99;
// return $;
}
$num=[10];
fun($num); //相对于fun方法来说 num是实参
var_dump($num);
/*
array (size=1)
0 => int 10
*/ ?>

思考: 正因为js中 function的形参若为引用类型时,可以影响实参! 推断 callback中参数原理

     function fun(data,callback){
var json=[1,2,3];
callback(json)
} var data=[];
fun(data,function(result){
data=result;
})
console.log(data)//[1, 2, 3]

如上例子 在回调函数中修改了 变量 data

知识点1、 function 是一种数据类型,可以当做参数传递 2、数组是引用类型 3、引用类型的形参会影响实参

 <body>
<button onclick='log()'>ajax</button>
</body>
<script>
function fun(data,callback){
setTimeout(function(){
var json=[1,2,3];
callback(json)
},4000) } var data=[];
fun(data,function(res){
data=res;
})
console.log(data)//[]
function log(){
console.log(data)//[1, 2, 3] 4秒后输出
} </script>

使用 setTimeout 模拟ajax请求! 

参考地址:http://www.w3school.com.cn/js/pro_js_value.asp

http://www.qdfuns.com/notes/17660/7f82003c5ce92d39d19d6be0403f3f3b.html

 

js按值传递和按引用传递的更多相关文章

  1. js按值传递还是按引用传递?

    js和其他大部分语言一样,有基本类型和引用类型.因此访问变量就有按值和按引用两种方式,但是传参的时候却只能按值传递.基本类型作为参数时按值传递自然无可厚非,但引用类型作为参数也按值传递就让人有点困惑了 ...

  2. JS是按值传递还是按引用传递?【转载】

    最近遇到个有趣的问题:“JS中的值是按值传递,还是按引用传递呢?” 在分析这个问题之前,我们需了解什么是按值传递(call by value),什么是按引用传递(call by reference). ...

  3. Java参数按值传递?按引用传递

    有时候在想,java在调用方法时候究竟是按值传递还是按引用传递,之前有人说是基本数据类型按值传递,引用类型按引用传递.一时间,似乎都有道理. 笔者在此不追究字眼上的辨别识字能力,把自己对这个问题的理解 ...

  4. JavaScript中函数参数的按值传递与按引用传递(即按地址传递)

    首先声明一句:JavaScript中所有函数的参数都是按值传递的!不存在按引用传递! 在讲传递参数之前我们先来讲一下指针. 学过C指针的应该都知道,指针变量中保存的是一个地址,程序可以根据所保存的地址 ...

  5. PHP中对象是按值传递还是按引用传递?

    1.首先,什么是按值传递和按引用传递? 按值传递就是仅仅把值传递过去,相当于传递的是值的拷贝,而按引用传递传递的是内存的地址. 在 PHP5 中,如果按引用传递,就是将 zval 的地址赋给另一个变量 ...

  6. Java的按值传递和按引用传递解说

    在网上看到的一个帖子解释Java的按值传递和按引用传递,感觉挺全面,就转过来,以供以后学习参考: 1:按值传递是什么 指的是在方法调用时,传递的参数是按值的拷贝传递.示例如下: public clas ...

  7. 编程细节 —— 按值传递、按引用传递(final、const)

    System.out,out 是 System 类内定义的静态 final PrinterStream 变量: public final class System { ... public final ...

  8. 转------深入理解--Java按值传递和按引用传递

    引言 最近刷牛客网上的题目时碰到不少有关Java按值传递和按引用传递的问题,这种题目就是坑呀,在做错了n次之后,查找了多方资料进行总结既可以让自己在总结中得到提高,又可以让其他人少走弯路.何乐而不为? ...

  9. JS是按值传递还是按引用传递

    按值传递(call by value)是最常用的求值策略:函数的形参是被调用时所传实参的副本.修改形参的值并不会影响实参. 按引用传递(call by reference)时,函数的形参接收实参的隐式 ...

随机推荐

  1. Android Realm数据库使用指南

    Android Realm数据库使用指南 Realm数据库, 目前有Java, Objective‑C, React Native, Swift, Xamarin的几种实现, 是一套用来取代SQLit ...

  2. vsftp之虚拟用户

    1.安装: yum install -y vsftpd yum install -y lftp2.创建用户useradd virftp -s /sbin/nologin3.创建虚拟用户及其存放路径vi ...

  3. Material Design学习-----FloatingActionButton

    FloatingActionButton是悬浮操作按钮,它继承自imageview,所以说它具备有imageview所有的方法和属性.与其他按钮不同的是,FloatingActionButton默认就 ...

  4. 第21篇 js四种继承方式

    js是一个很自由的语言,没有强类型的语言的那种限制,实现一个功能往往有很多做法.继承就是其中的一个,在js中继承大概可以分为四大类,上面一篇文章也提及过一些,下面开始详细说说js的继承. 1.原型继承 ...

  5. 数据存储与访问之——初见SQLite数据库

          本节引言: 本节学习Android数据库存储与访问的第三种方式:SQLite数据库,和其他的SQL数据库不同,我们并不需要在手机上另外安装一个数据库手机软件,Android系统已经集成了这 ...

  6. 简单分析beyond作曲

    本人绝对是业余的哈 业余到什么水平呢?正在练习爬格子,还是一个星期练几次那种 先说下<海阔天空> 6,5,4,3 1,2,3,4 简单是简单得不得了,声从低到高,然后再从高到低,产生一种回 ...

  7. nodejs中的路由

    一.路由初步 url.parse(string).query | url.parse(string).pathname | | | | | ------ -------------------http ...

  8. 数据库-增删改查操作SQL实现

    一.数据插入-Insert 1. 插入单条记录 insert into 表名(字段名,字段名,字段名) //当插入所有字段时,字段名可以省略 values('值1','值2','值3'); 2. 插入 ...

  9. 浅谈HTML5中的浮动问题

    浮动是我们在前端页面中经常会用到的一种布局方式.那什么是浮动呢? 首先我们先来看一下它的定义.浮动是指让元素脱离文档标准流(脱标),按照指定的方向去横向排列.浮动的取值有两个,分别是float:lef ...

  10. subline text3常用插件介绍

    常用插件介绍:  html beautify(ctrl+shift+alt+f) 自动排版代码 Emmet 输入少量代码后摁Tab键,系统自动补全代码. AutoFileName 快速列出你想引用的文 ...