JavaScript函数传参原理详解——值传递还是引用传递

article/2025/3/4 19:17:35

讨论JavaScript的传参原理之前,我们先来看一段曾经让笔者困惑了一段时间的代码

var testA=1;
var testB={};
function testNumber(example){example=2;
}function testObj(example) {example.test=1;
}testNumber(testA);
testObj(testB);
console.log(testA);//输出1
console.log(testB);//输出{test:1}

上述代码展示了一个比较纠结的问题:传入一个变量到函数中,函数对这个变量进行修改,到底会不会影响到原变量?从上面的代码我们可以发现,两者都可能出现。那到底是为什么呢?

解答这个问题之前,我们先来了解一下编程语言中函数传参的常用方式

穿插科普——实参和形参

所谓形参,是指我们定义函数的时候,函数定义的参数,例如上述代码中,testNumber函数定义中,example就是形参。

所谓实参,是指我们调用函数的时候,实际传入的值,例如上述代码中,testNumber(testA),此时testA为实参。

按值传递

按值传递是一种比较容易理解又使用比较广泛的传参方式,这种方式在传参的时候,在内存中会直接把实参的值复制一份再把副本传递给形参,对于形参的修改并不会影响到实参

按引用传递

按引用传递相对来说比较难理解,如果函数使用按引用传递,那么形参将会直接接收实参的引用,而不经过复制,那么此时对于形参的修改则会影响到实参。难以理解?看图(注意,图示仅为举例用于说明按引用传递,事实上图示的情况在js中并不会出现,具体原因下文会有说明)

由于在js中,引用类型在内存中分两部分存放,实际的值存放在堆中,在栈中会存放引用类型位于堆中的地址,而我们平时操作的,都是通过栈中的地址对对象进行操作的,那么如果使用按引用传递,就意味着操作的是同一个地址,对于形参的修改就会影响到实参

js中的传参策略

那么按照上面的分析,可能会有人认为,在js中,对于值类型是按值传递,对于引用类型是按引用传递,然而,这是错误的。事实上,在js中,不管对于值类型还是引用类类型,都是按值传递的,区别在于,对于值类型,传参发生时,复制的是类型本身的值,而对于引用类型,复制的是类型的地址。我们来看下面这段代码,可以用来否定引用类型是按引用传参这个观点

var testC={};
function testObject(example){example={b:1};
}
testObject(testC)
console.log(testC);//输出{},实参并没有改变

通过上面的代码我们可以看出,如果是按引用传参,那么直接修改形参,是会对实参造成影响的,但是我们发现事实上并没有,为了方便理解,下面给出JavaScript中值类型和引用类型进行传参时在内存中的实际复制情况

值类型

引用类型

总结

对于js中的变量,值类型存放在栈中,引用类型的地址存放在栈中,对应的值存放在堆中。当传参发生的时候,值类型会直接将栈中的值进行复制,形参和实参此时实际上是两个完全不相干的变量。对于引用类型,传参发生时,会将实参变量位于栈中的地址进行复制,此时栈中会有两个指向同一个堆地址的指针。

啰嗦一下对比testObj和testObject两个函数的不同效果

我们回头看一下上面举例的两个函数,都是直接对形参进行修改,为什么一个影响到了实参,而另一个却完全没有影响呢?为了方便对比,我们把它们放到一起

var testB={};
var testC={};
function testObject(example){example={b:1};
}function testObj(example) {example.test=1;
}testObject(testC);
testObj(testB);
console.log(testC);//输出{}
console.log(testB);//输出{test:1}

事实上,由于对引用对象的地址复制,形参和实参之间还是存在关联的,地址指向了同一个对象,也就是说我们调用testObj操作形参时,对应操作的对象也是实参。但是调用testObject时,就是另一种状况了,当我们直接将形参替换成另一个值,在内存中会形成下图的情况

此时,形参会指向堆中的另一个值,形参和实参从此彻底分道扬镳,无论怎么修改,都不会互相影响了

如有不同看法,欢迎留言指教


http://chatgpt.dhexx.cn/article/cw1SMTha.shtml

相关文章

javascript 函数传参

通过值传递参数 在函数中调用的参数是函数的隐式参数。 JavaScript 隐式参数通过值来传递:函数仅仅只是获取值。 如果函数修改参数的值,不会修改显式参数的初始值(在函数外定义)。 隐式参数的改变在函数外是不可见的。 通过对…

前端基础知识点:JS中的参数传递详解

JS语法中的传递参数,对于初学者是一个非常重要的概念。很多小伙伴在学习“值传递”和“引用传递”时,会有不少烦恼。今天我们就来通过各种姿势全方位剖析JS中的值传递。 本文章将会用10分钟时间无死角的解析JS的传参方式,希望能对您有所帮助…

Javascript基础知识(三):函数参数(传参)

1.函数参数分类及使用 上一篇博客已经讲到函数参数有实参和形参两种。 函数参数使用时需要注意以下几点&#xff1a; 1.如果形参有两个赋值&#xff0c;而实参只给了一个值&#xff0c;那么就要把这个值赋予第一个形参.第二个形参没有赋值。 示例&#xff1a; <script&g…

js 基础-函数传参

函数中的参数传递是所有编程语言的中的基础内容。本文是介绍了js中保存基本数据类型和引用数据类型的两种方式以及在函数传参的本质。 1 简介 本文介绍了js中两种不同数据类型的数据的保存问题&#xff0c;以及赋值操作的本质&#xff0c;最后指出函数传参就是赋值操作&#…

php获取qq音乐的api类,利用QQ音乐api集成的php歌曲搜索

获取最新音乐 url&#xff1a; https://c.y.qq.com/v8/fcg-bin/fcg_v8_toplist_cp.fcg?uin0&notice0&platformh5&needNewCode1&tpl3&pagedetail&typetop&topid27 获取推荐歌曲 url&#xff1a; https://c.y.qq.com/v8/fcg-bin/fcg_v8_toplist_cp.…

Vue之跨域调用网易云音乐API及QQ音乐API

今天在做VUE项目的时候&#xff0c;发现调用QQ音乐轮播图的API一直失败&#xff0c;timeout真的不是我网络的问题&#xff0c;在客厅对着路由器调了一整天都是报错&#xff0c;我还以为是API失效了&#xff0c;但其实没有........晚上突然又可以获取了 但总不能不写轮播图吧&am…

MusicBee 歌词插件(基于QQ音乐API)

MusicBee 歌词插件&#xff08;基于QQ音乐API&#xff09; MusicBee 是一个很棒的免费音乐管理、播放软件&#xff0c;支持通过插件来扩展功能。然而 MusicBee 在初始情况下仅对外国的几个歌词数据库进行检索&#xff0c;得到的结果一般是不带时间轴的纯文本歌词&#xff0c;并…

php开发个人音乐站 QQ音乐api

做位一名优秀的程序员 工作时候戴耳机是不可避免的 然后好听的歌又需要会员 下面小编就给大家简绍我自己听歌的神器 话不多说 开撸&#xff01; 一&#xff0c;要想获得对应的歌曲肯定要先获得歌曲的id,图片id等 下面主要讲解如何获取歌曲播放id&#xff1b; 1.搜索歌曲API&a…

python调用QQ音乐API

python调用QQ音乐API 1. 音乐搜索接口、其他接口 2. 获取token 3. 拼接播放地址 先上一份代码&#xff1a; import requests import pprint import json from selenium import webdriver# 音乐搜索接口p, n, w 1, 5, 碰 url_1 https://c.y.qq.com/soso/fcgi-bin/client_…

php计算QQ音乐guid,QQ音乐API分析2017

官网提供API 说明&#xff1a;此API主要针对移动端直接调用QQ音乐API用&#xff0c;API只能在QQAPP内执行&#xff0c;上线时间尚短。 http://y.qq.com/m/api/api.html 自己分析的API 说明&#xff1a; 根据官网https://y.qq.com/分析的API&#xff0c;经过测试&#xff0c;可以…

java qq音乐接口 api,GitHub - yan123zi/qqMusicApi: qq音乐Api接口

qq音乐 API qq音乐 Node.js API service QQ音乐API koa2 版本, 通过Web网页版请求QQ音乐接口数据, 有问题请提 issue 当前代码仅共学习&#xff0c;不可做商业用途 API结构图 环境要求 因为本项目采用的是koa2, 所以请确保你的node版本是7.6.0 node -v &#x1f4e6; 安装 git…

QQ音乐API整理

最近准备用vue做个音乐播放器&#xff0c;网上找了找音乐API&#xff0c;看了一圈&#xff0c;还是QQ音乐最合适&#xff0c;这里做个整理 这篇博客已经过时了&#xff0c;下面的不用看了。。。。 歌曲搜索 接口地址 var num 3,name 王菲,urlString http://s.music.qq.co…

网易云音乐api、QQ音乐api、黑马电商api、小说api、漫画api接口

网易云音乐接口文档 基础访问地址&#xff08;api的跟地址&#xff09;&#xff1a;https://autumnfish.cn/ 接口文档地址&#xff1a;https://binaryify.github.io/NeteaseCloudMusicApi/ QQ音乐接口文档 基础访问地址&#xff08;api的跟地址&#xff09;&#xff1a;http…

QQ音乐API

** QQ音乐API ** 效果图: URL: 通过这条接口查找到这10条歌曲每一条的Songmid https://c.y.qq.com/soso/fcgi-bin/client_search_cp?aggr=1&cr=1&flag_qc=0&p=1&n=10&w=邓紫棋; 这条链接获取到QQ音乐当前使用的地址(QQ音乐不定期换地址,本人跳过这…

2019最新版QQ音乐api调用(原创)

下载QQ音乐任意歌曲方法&#xff1a; 1.首先在QQ音乐任意播放页面 2.进入开发者模式按F12即可 3.选择network&#xff0c;按ctrlR进行筛选多媒体文件 4.优先选择大小排序右击最大的多媒体文件出来快捷菜单&#xff0c;选择如下图的选项即可进入歌曲播放页面 5.如下链接就是播放…

QQ音乐api 最新版,亲测可用

关注公众号&#xff0c;每天都能领红包 最近这个api出现了403问题&#xff0c;已经找到原因了 原因是 歌曲不能再以第一参数当id了 要以倒数第5个 如以上的例子 002qU5aY3Qu24y当id&#xff0c;而且前面要加C100&#xff0c;完整的就是 http://ws.stream.qqmusic.qq.com/C1000…

Java版本中最好用的网易云音乐、qq音乐api请求工具,你还在忙于如何使用java调音乐api?来看下这里的实现

去年闲着没事干&#xff0c;就封装了下面QQ和Netease音乐的 api &#xff0c;目的就是通过java可以更便捷的调用&#xff0c;网易云音乐或者qq音乐的api&#xff0c;另外每个接口我都加了注释&#xff0c;对于不懂的参数&#xff0c;通过接口上的注释直接可以查看&#xff0c;不…

QQ音乐API爬取全过程

QQ音乐API爬取全过程 1. 前序&#xff1a; 在以前的QQ音乐的API爬取中&#xff0c;是非常容易的&#xff0c;采用的是jsonp的请求方式&#xff0c;但现在QQ音乐请求已经全部改成XHR的ajax的方式发送请求&#xff0c;所以要爬取QQ音乐的数据就需要破解QQ音乐发送请求的参数。 …

QQ音乐API分析之-加密参数分析(sign计算)

QQ音乐API加密参数分析 1、背景2、QQ音乐sign计算3、Java代码实现4、总结 1、背景 不知道什么时候开始&#xff0c;各家音乐APP都开始对API进行加密&#xff0c;最近一段时间对六大音乐平台的加密算法进行了研究&#xff0c;逆向了网页端、安卓端等等&#xff0c;已经掌握了各…

微信小程序使用QQ音乐API完整实例

微信小程序使用QQ音乐API完整实例 一、QQ音乐常用API接口&#xff1a;1.1、音乐搜索接口&#xff1a;1.2、最新音乐排行榜top1001.3. 随机推荐 二、请求数据格式&#xff08;以搜索为例&#xff09;三、播放链接&#xff08;重点&#xff09;3.1、获取歌曲信息3.2 获取token3.3…