JS参数之按值传递、引用传递和共享传递

圣人不死,大盗不止。 --庄子·外篇·胠箧第十

在JavaScript中,参数的数据传递方式一般是按值传递、引用传递,今天遇到有人问如下这个问题

ini 复制代码
const obj = {
  value: 1
};

function foo(o) {
  o = 2;
  console.log(o); //2
}

foo(obj);
console.log(obj.value); // 1
console.log(obj); // { value: 1 }

问为什么obj的值没有改变,按照引用传递的方式,最后一行打印的值不是2,而是{ value: 1 },

一开始给我也问懵了。确实,最近写iOS代码比较多,按照OC语言的逻辑,如果原先存在一个引用型数据类型A,给这个A赋值引用数据类型B,那么就会A等于B,A和B的内存地址是同一块,原先的A就不存在了。如果按照这个逻辑,确实应该打印2,但是!这是JS,不是OC,反应了片刻,和他简单介绍了JS参数传递的几种方式:

按值传递

这个是最基本的传递方式,最符合直观认知的。大家看一下代码就会明白,即使不会JS会、没啥编程经验的人也能理解。

scss 复制代码
function add(param){
  param+=10;
  console.log(param);//11
}

const num = 1;
add(num);
console.log(num);//1

这里,参数param的改变对于num是没有任何影响的,因为这里是num的值复制给了函数add内部的局部变量param,所以在函数内部改变param的值并不会影响外部num的值。

引用类型

红宝书中这么介绍引用类型的:

ECMAScript 中所有函数的参数都是按值传递的。这意味着函数外的值会被复制到函数内部的参数 中,就像从一个变量复制到另一个变量一样。如果是原始值,那么就跟原始值变量的复制一样,如果是 引用值,那么就跟引用值变量的复制一样。

话不多说,上代码:

kotlin 复制代码
const value = {
  value: 1
};

function fun(o) {
  o.value = 2;
  console.log(o.value);//2
  console.log(o);//{value: 2}
}

fun(value);
console.log(value);//{value: 2}
console.log(value.value);//2

函数内部对形参的操作影响到了外部实参,这里就是引用类型。hba

共享类型

那什么是共享类型呢?

说实话我暂时没在红宝书中找到这种说话,但是'坊间'一直流传着共享类型的传说。

还是刚刚那段代码:

ini 复制代码
const obj = {
  value: 1
};

function foo(o) {
  o = 2;
  console.log(o); //2
}

foo(obj);
console.log(obj.value); // 1
console.log(obj); // { value: 1 }

简单来说就是:对于传递到函数参数的对象类型,如果直接改变了拷贝的引用的指向地址,那是不会影响到原来的那个对象;如果是通过拷贝的引用,去进行内部的值的操作,那么就会改变到原来的对象的。

意味着,这段代码的执行关键就在 o = 2;将原先存放参数o的内存地址,存放了2(这里可能对于地址更换的细节有出入,但是不影响理解),也就是原先的参数o和obj没有任何关系了,转而存放了2这个值,赋值操作导致标识符发生了重新绑定Rebinding,重新复制的标识符会指向新的内存空间。

相关推荐
风无雨8 分钟前
GO启动一个视频下载接口 前端可以边下边放
前端·golang·音视频
Rainbow_Pearl13 分钟前
Vue2_element 表头查询功能
javascript·vue.js·elementui
aha-凯心1 小时前
前端学习 vben 之 axios interceptors
前端·学习
熊出没1 小时前
Vue前端导出页面为PDF文件
前端·vue.js·pdf
VOLUN1 小时前
Vue3项目中优雅封装API基础接口:getBaseApi设计解析
前端·vue.js·api
此乃大忽悠1 小时前
XSS(ctfshow)
javascript·web安全·xss·ctfshow
用户99045017780091 小时前
告别广告干扰,体验极简 JSON 格式化——这款工具让你专注代码本身
前端
前端极客探险家1 小时前
告别卡顿与慢响应!现代 Web 应用性能优化:从前端渲染到后端算法的全面提速指南
前端·算法·性能优化
袁煦丞2 小时前
【局域网秒传神器】LocalSend:cpolar内网穿透实验室第418个成功挑战
前端·程序员·远程工作
江城开朗的豌豆2 小时前
Vuex数据突然消失?六招教你轻松找回来!
前端·javascript·vue.js