0

0

JavaScript参数传递中值和引用的一种理解的详细介绍

黄舟

黄舟

发布时间:2017-03-04 16:09:16

|

1473人浏览过

|

来源于php中文网

原创

值(value)和引用(reference)是各种编程语言老生常谈的话题,js也不例外。

我将剖析一个例子的实际运行过程,跟大家分享我对js参数传递中的值和引用的理解。

参考官网数据类型的两种分类,本文将这两种分类简称为基本类型(boolean, null, undefined, string, number, symbol)和object类型。

首先,用一个example 演示参数传递的应用:

立即学习Java免费学习笔记(深入)”;

var obj = {};
obj.inner = 10;

var num = 10;
var str = 'Hello';
var boo = true;
var oth = null;
var und = undefined;
var sym = Symbol('foo');

function passingobject(myobj){
    myobj.inner  = 1 + myobj.inner ; 
}

function passingvalue(myvalue){
  switch(typeof myvalue){
    case 'number':
        myvalue = myvalue + 1;
        break;
      case 'string':
        myvalue = 'I am a new string now!';
        break;
      case 'boolean':
        myvalue= false;
        break;
      default:
        myvalue = 'Null, Undefined, or Symbol';
     }
  }

  console.log("before num = " + num);  // before num = 10
  passingvalue(num);
  console.log("after num = " + num);  // after num = 10
  console.log("before str = " + str); // before str = Hello
  passingvalue(str);
  console.log("after str = " + str);  // after str = Hello
  console.log("before boo = " + boo); // before boo = true
  passingvalue(boo);
  console.log("after boo = " + boo);  // after boo = false
  console.log("before oth = " + oth); // before oth = null
  passingvalue(oth);
  console.log("after oth = " + oth);  // after oth = null
  console.log("before und = " + und); // before und = undefined
  passingvalue(und);
  console.log("after und = " + und);  // after und = undefined
  console.log(sym); // Symbol(foo)
  passingvalue(sym);
  console.log(sym); // Symbol(foo)
  console.log("before obj.inner = " + obj.inner); // before obj.inner = 10
  passingobject(obj); // after obj.inner = 11
  console.log("after obj.inner = " + obj.inner);

从example 1 的结果似乎可以总结出以下两条结论:

1. 传递的数据类型为基本类型(number, string boolean, null, undefined, symbol),在参数传递过程中,函数内部对传递值的操作并不影响原始值。

2. 传递的数据类型为object, 在参数传递过程中,函数内部对传递值的操作会导致原始值的改变。

然而, 有没有其他特殊情况呢?

有一种在stackoverflow讨论很火热的用法,跟结论二背道而行。example 2。

 1 function changeStuff(a, b, c)
 2 {
 3   a = a * 10;
 4   b.item = "changed";
 5   c = {item: "changed"};
 6 }
 7 
 8 var num = 10;
 9 var obj1 = {item: "unchanged"};
10 var obj2 = {item: "unchanged"};
11 
12 console.log(obj1.item); // unchanged
13 console.log(obj2.item); // unchanged
14 changeStuff(num, obj1, obj2);
15 console.log(obj1.item); // changed
16 console.log(obj2.item); // unchanged

example 2中, obj2.item并没有被函数changeStuff改变。changeStuff内部同样改变了b、c的值,为什么obj1被改变了(L15)而obj2没有被改变呢?

我用js的执行上下文对这种现象进行解释,如图。

在js运行过程中,编辑器动态生成执行上下文(execution context),example 2中,首先生成global的执行上下文和changeStuff的执行上下文。

企业后台管理系统JaManage2.0 多语言版
企业后台管理系统JaManage2.0 多语言版

功能介绍: 一.系统管理:管理员管理,可以新增管理员及修改管理员密码;数据库备份,为保证您的数据安全本系统采用了数据库备份功能;上传文件管理,管理你增加产品时上传的图片及其他文件 二.企业信息:可设置修改企业的各类信息及介绍 三.产品管理:产品类别新增修改管理,产品添加修改以及产品的审核 四.下载中心:可分类增加各种文件,如驱动和技术文档等文件的下载 五.订单管理:查看订单的详细信息

下载

执行到changeStuff(num, obj1, obj2)的时候, a, b, c指向参数num, obj1, obj2,a和num指向10, b跟obj1指向同一个值,c跟obj2指向同一个值。

执行step 1的时候,对a重新赋值,为a赋值前的10倍,从此a与num毫无关系。

执行step 2的时候,对b所指向的值的item属性进行重新赋值,这个赋值只改变了item的值, 而obj1和b仍然指向同一个值。

执行step 3的时候,对c重新赋值,从此c与obj2再无瓜葛,因此即使c有一个叫item的属性,与obj2的item属性有着各自的值,并没有影响obj2.item。

也就是说,js函数参数传递过程中,若函数内部对参数重新赋值,这个赋值过程不会影响原始变量的值。

这也很好地解释了基本类型的参数变量(结论1)不会受影响的现象,基本类型的参数变量每一次改变都是一次全新赋值,对原始变量不会造成影响。

总结

在js函数传递中,当基本类型(number, string, boolean, null, undefined, symbol)变量作为参数传递时,函数内部对参数的任何操作都不会改变变量的值。

当object类型变量作为参数传递时,函数内部对参数的操作会影响变量的值,除非函数内部对参数重新赋值(任何类型的值)。

Thank you!

Feel free to contact me if you have any question!

 以上就是JavaScript参数传递中值和引用的一种理解的详细介绍的内容,更多相关内容请关注PHP中文网(www.php.cn)!

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

23

2026.01.19

java用途介绍
java用途介绍

本专题整合了java用途功能相关介绍,阅读专题下面的文章了解更多详细内容。

11

2026.01.19

java输出数组相关教程
java输出数组相关教程

本专题整合了java输出数组相关教程,阅读专题下面的文章了解更多详细内容。

3

2026.01.19

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

2

2026.01.19

xml格式相关教程
xml格式相关教程

本专题整合了xml格式相关教程汇总,阅读专题下面的文章了解更多详细内容。

4

2026.01.19

PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

13

2026.01.19

微信聊天记录删除恢复导出教程汇总
微信聊天记录删除恢复导出教程汇总

本专题整合了微信聊天记录相关教程大全,阅读专题下面的文章了解更多详细内容。

93

2026.01.18

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

112

2026.01.16

全民K歌得高分教程大全
全民K歌得高分教程大全

本专题整合了全民K歌得高分技巧汇总,阅读专题下面的文章了解更多详细内容。

155

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.8万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.3万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号