0

0

在js中函数的传递方式是怎样的

不言

不言

发布时间:2018-07-16 16:02:17

|

2145人浏览过

|

来源于php中文网

原创

最近学习js的过程中碰到了js函数参数传递对象的问题,也研究了关于引用传递和值传递的问题,虽说也花费了一些时间,不过总算明白了。

数据类型

   在 javascript 中数据类型可以分为两类:

基本类型值 primitive type,比如Undefined,Null,Boolean,Number,String。

引用类型值,也就是对象类型 Object type,比如Object,Array,Function,Date等。  

变量的复制

   众所周知,js中变量的基本类型和引用类型保存方式是不同的,这也就导致变量复制时也就不同了。如果从一个变量向另一个变量复制基本类型的值时,会将前者的值克隆一个,然后将克隆的值赋值到后者,因此这两个值是完全独立的,只是他们的value相同而已。

var num1 = 10;var num2 = num1;
console.log(num2);//10

上面的num1中被保存的值为10,当把num1的值赋值给num2时,num2的值也为10。但是这两个10是完全独立的,num2中的10只是被克隆出来的,相当于我写了一个word文档,把它放到了num1的文件夹中,然后我再复制这个word文档,就叫word副本吧,然后把这个副本放到num2的文件夹下,这两个word文档是完全一样的,修改任何一个都不会影响两一个。

num2 += 1;
console.log(num1); //10
console.log(num2); //11

从上面可以看出修改num2的值,num1的值未发生变化。再来看下引用类型的复制。当从一个变量向另一个变量复制引用类型的值时,同样也会将存储在变量对象中的值复制一份放到为新变量分配的空间中。

var obj1 = {
  name : "111"};var obj2 = obj1;
console.log(obj2.name); //111
obj2.name = "222";
console.log(obj1.name); //222

第一次打印出的结果为“111”,这个我们很容易理解,但是第二次打印出来的是“222”,有点莫名其妙了。这就是引用类型和基本类型的不同之处了。复制对象时并不会在堆内存中新生成一个一模一样的对象,只是多了一个保存指向这个对象指针的变量罢了。将obj1的值复制给obj2,而这个值的副本实际上是一个指针,这个指针指向存储在堆中的一个对象,也就是说创建了一个新的内存地址传给了obj2,obj1和obj2两个变量同时指向了同一个Object,当去改变这个对象时,他们的值都会改变,也就是说他们中任何一个作出的改变都会反映在另一个身上。下面的简易图可能更明了些。

函数参数的传递 

      《js高级程序设计》上是这样叙述参数传递的:所有函数的参数都是按值传递的,也就是说把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。所以如果能理解变量的复制,那么参数的传递也就很简单了。还是先从基本类型举例说明吧。

2088shop商城购物系统
2088shop商城购物系统

2088shop商城购物系统是商城系统中功能最全的一个版本:非会员购物、商品无限级分类、不限商品数量、商品多级会员定价、上货库存、Word在线编辑器、订单详情销售报表、商品评论、留言簿、管理员多级别、VIP积分、会员注册积分奖励、智能新闻发布、滚动公告、投票调查、背景图片颜色更换、店标上传、版权联系方式修改、背景音乐(好歌不断)、广告图片支持Flash、弹出浮动广告、搜索引擎关健词优化、图文友情联

下载
var count = 10;function num(num1){
   num1 = 1;
   return num1;
}var result = num(count);console.log(result);//1
console.log(count);//10,并未变成1

这个例子很容易理解,实际就是创建了一个count的副本,然后把count的值传入参数中,因为函数中定义了参数的值,所以1就将10覆盖了,最后的result返回1,而count并未发生变化。看一个有关传递对象的例子。

var person  = {
    name : "Tom"};function obj(peo){
    peo.name = "Jerry";
    return peo;
}var result = obj(person);
console.log(result.name);// Jerry
console.log(person.name);// Jerry

在上面的例子中,把person复制传入obj()中,peo和person指向了同一个对象,而在peo中修改了name属性,其实修改了它们共同指向的对象的name属性,相对应的外部person所引用的name属性也就改变了,所以打印出来的为Jerry。其实这个乍一看,感觉引用类型的参数是按照引用传递的,这就是我最初犯得错误。再来看一个例子。

var person = {
    
name : "Tom"}; 
 function obj(peo){
    
peo = {
      
 name : "Jerry"
    };    
return peo; 
}
var result = obj(person);console.log(result.name);// Jerry

console.log(person.name);// Tom

上面的例子中,在函数中重新定义了一个对象,也就是现在堆内存中有两个对象,外部的person指向的是老的对象,被传入参数后指向的是新定义的对象,所以调用后返回的值是新定义的对象的值。如果是参数是按引用传递的,那么person.name打印出来的结果为Jerry,从这点可以得出参数是按值传递的(有的地方叫做按共享传递)。

我们拿老罗推荐的《人类简史》把它形象化,描述的不太好。简史的第一章标题是“认知革命”,我们把它名字改为“person”根据后面的页码数可以直接找到“认知革命”的内容“也就是peoson所指向的对象”,第二章是“农业革命”,我们把它为“result”,其分目录有一节“记忆过载”(改名为“peo”),同样可以直接根据页码找到这一节内容。现在我们把“person”复制到“peo”中,第二章中的“peo”这一节就变成了“person”,而我们根据第一章中的“peoson”找到的还是第一章的内容,这是因为它们指向了不同的内容板块,互不干扰。在这里,堆内存就是每章的内容,而第一章和第二章内容是2个不同的对象,而这两者互不相干,因此打印外部person.name时,结果仍是以前的对象的属性值。

结论

总而言之,在js中参数都是按值传递的。我写例子粗糙了些,《javascript高级程序设计》中的例子描述的更清晰一些,更易理解。

相关推荐:

js中函数参数的实现原理

对js函数的实参,形参以及闭包的理解      

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python 序列化
Python 序列化

本专题整合了python序列化、反序列化相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.02.02

AO3官网入口与中文阅读设置 AO3网页版使用与访问
AO3官网入口与中文阅读设置 AO3网页版使用与访问

本专题围绕 Archive of Our Own(AO3)官网入口展开,系统整理 AO3 最新可用官网地址、网页版访问方式、正确打开链接的方法,并详细讲解 AO3 中文界面设置、阅读语言切换及基础使用流程,帮助用户稳定访问 AO3 官网,高效完成中文阅读与作品浏览。

91

2026.02.02

主流快递单号查询入口 实时物流进度一站式追踪专题
主流快递单号查询入口 实时物流进度一站式追踪专题

本专题聚合极兔快递、京东快递、中通快递、圆通快递、韵达快递等主流物流平台的单号查询与运单追踪内容,重点解决单号查询、手机号查物流、官网入口直达、包裹进度实时追踪等高频问题,帮助用户快速获取最新物流状态,提升查件效率与使用体验。

27

2026.02.02

Golang WebAssembly(WASM)开发入门
Golang WebAssembly(WASM)开发入门

本专题系统讲解 Golang 在 WebAssembly(WASM)开发中的实践方法,涵盖 WASM 基础原理、Go 编译到 WASM 的流程、与 JavaScript 的交互方式、性能与体积优化,以及典型应用场景(如前端计算、跨平台模块)。帮助开发者掌握 Go 在新一代 Web 技术栈中的应用能力。

11

2026.02.02

PHP Swoole 高性能服务开发
PHP Swoole 高性能服务开发

本专题聚焦 PHP Swoole 扩展在高性能服务端开发中的应用,系统讲解协程模型、异步IO、TCP/HTTP/WebSocket服务器、进程与任务管理、常驻内存架构设计。通过实战案例,帮助开发者掌握 使用 PHP 构建高并发、低延迟服务端应用的工程化能力。

5

2026.02.02

Java JNI 与本地代码交互实战
Java JNI 与本地代码交互实战

本专题系统讲解 Java 通过 JNI 调用 C/C++ 本地代码的核心机制,涵盖 JNI 基本原理、数据类型映射、内存管理、异常处理、性能优化策略以及典型应用场景(如高性能计算、底层库封装)。通过实战示例,帮助开发者掌握 Java 与本地代码混合开发的完整流程。

5

2026.02.02

go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

62

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

55

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

27

2026.01.31

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
微信小程序开发之API篇
微信小程序开发之API篇

共15课时 | 1.3万人学习

Swoft2.x速学之http api篇课程
Swoft2.x速学之http api篇课程

共16课时 | 0.9万人学习

PHP基础入门课程
PHP基础入门课程

共33课时 | 2万人学习

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

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