深入学习 JavaScript中的函数调用
发布时间 - 2026-01-11 00:19:14 点击率:次定义

可能很多人在学习 JavaScript 过程中碰到过函数参数传递方式的迷惑,本着深入的精神,我想再源码中寻找些答案不过在做这件事之前,首先明确几个概念。抛弃掉值传递、引用传递等固有叫法,回归英文:
call by reference && call by value && call by sharing
分别是我们理解的 C++ 中的引用传递,值传递。第三种比较迷惑,官方解释是 receives the copy of the reference to object 。我用通俗的话解释一下:
Object 可以理解为 key 的集合,Object 对 key 指向的数据是引用性质的(这里不深究是指针实现还是C++引用实现),函数接收的是一个变量的 copy,变量包含了 Object 的引用 ,是一个值传递。
那么很明显,函数传参的时候我们接收到的对象型参其实是实参的复制,所以直接更改型参的指向是不可行的;由于 Object 本身的 key 都是引用,所以修改 key 的指向是可行的。
证明
简单来几段代码即可证明
Code 1: 函数能修改 key 指向的数据
let func = obj => { obj.name = 'Dosk' };
let obj = {name : 'Alxw'};
console.log(obj); //{ name: 'Alxw' }
func(obj)
console.log(obj); //{ name: 'Dosk' }
Code 2: 函数不能修改 obj
let func = obj => { obj = {} };
let obj = {name : 'Alxw'};
console.log(obj); //{ name: 'Alxw' }
func(obj)
console.log(obj); //{ name: 'Alxw' }
Code 3: 内部 obj 和外部 === 结果相等
let def = {name : 'Alxw'};
let func = obj => { console.log(obj === def) };
func(def); //true
所以第三段代码可能有疑问了,既然 obj 是 def 的复制,为什么 === 操作还能够为真?不是说 === 操作对于 Object 比较的是在内存中的地址么,如果是复制应该是 false 才对啊?
所以我们回到 Google V8 的源码来看这件事。
深入 Google V8
我们来看看源码里严格等于操作代码部分:
bool Object::StrictEquals(Object* that) {
if (this->IsNumber()) {
if (!that->IsNumber()) return false;
return NumberEquals(this, that);
} else if (this->IsString()) {
if (!that->IsString()) return false;
return String::cast(this)->Equals(String::cast(that));
} else if (this->IsSimd128Value()) {
if (!that->IsSimd128Value()) return false;
return Simd128Value::cast(this)->Equals(Simd128Value::cast(that));
}
return this == that;
}
看起来应该是最后一种情况,理论上如果 def 和 obj 是不同的对象,那么应该返回 false 才对,这不是推翻了上文所述么?其实不,忽略了一件事,即 Google V8 内部在实例化一个 Object 的时候,本身就是动态实例化,而我们知道在编译型语言中如果动态实例化只能够在堆内存上,即只能够指针引用。这个结论是的证明涉及到 Local 、Handle 等 class 的实现,我觉得太麻烦,有一个简单的证明方式,即搜索源码得到所有调用 Object::StrictEquals 的地方都是直接传入而没有取地址操作。
不过有人会问,既然是值传递的变量包含 Object 的引用,理论上也能够修改 Object 才对,为什么第三段代码不能修改呢?
很简单的道理,因为我们在 JavaScript 语言逻辑层次上的所谓的操作,只不过是在调用 Google V8 的实例方的法而已,根本不可能操作到这一地步(当然,潜在的 BUG 不算的 -。-)
重新定义
我觉得到这里可以给 call by sharing 重新解释一下了:
的确,传递的时候是值传递,但是内容包含了 Object 的指针,而且不能够修改这个指针,他是多个变量共享的。
另一种简单的证明
来来来,看源码
V8_DEPRECATE_SOON("Use maybe version",
Local<Value> Call(Local<Value> recv, int argc,
Local<Value> argv[]));
V8_WARN_UNUSED_RESULT MaybeLocal<Value> Call(Local<Context> context,
Local<Value> recv, int argc,
Local<Value> argv[]);
上面的是即将弃用的接口,碰巧我看到的这个版本代码包含大量的这种即将弃用的代码,看看就好。重点是第二个接口,是函数的唯一的调用的接口。里面的 Local<Value> 最终会调用 C++ 的位复制,所以可以简单的证明就是值传递。
可能是重点
别忘了,我们定义的的变量都是类似 Handle<Object> 这种形式的,所以它们之间对象才是共享的,我们所说的 JavaScript 里面变量并不直接指的是 Object 的实例!!!
最后的最后
总之理解起来可能很费劲甚至有错误,但是在 JavaScript 语言层次上能够确定了特性,这才是重要的。
以上所述是小编给大家介绍的JavaScript中的函数调用,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
# javascript函数调用
# JavaScript:new 一个函数和直接调用函数的区别分析
# JavaScript函数的4种调用方法实例分析
# JavaScript 函数的定义-调用、注意事项
# 浅谈js函数三种定义方式 & 四种调用方式 & 调用顺序
# javascript函数的四种调用模式
# Javascript 函数的四种调用模式
# 深入理解JavaScript中的尾调用(Tail Call)
# javascript使用call调用微信API
# 基于JavaScript实现继承机制之调用call()与apply()的方法详解
# javaScript call 函数的用法说明
# JavaScript中的apply和call函数详解
# JavaScript直接调用函数与call调用的区别实例分析
# 的是
# 都是
# 我觉得
# 这件事
# 才对
# 所述
# 小编
# 应该是
# 是一个
# 第三段
# 几个
# 这一
# 是在
# 不可能
# 包含了
# 他是
# 多个
# 才是
# 在此
# 就好
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
IOS倒计时设置UIButton标题title的抖动问题
laravel怎么通过契约(Contracts)编程_laravel契约(Contracts)编程方法
Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】
浅述节点的创建及常见功能的实现
Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】
Android实现代码画虚线边框背景效果
公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?
浅析上传头像示例及其注意事项
Laravel怎么为数据库表字段添加索引以优化查询
如何登录建站主机?访问步骤全解析
如何在云主机上快速搭建多站点网站?
详解阿里云nginx服务器多站点的配置
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
Mybatis 中的insertOrUpdate操作
手机怎么制作网站教程步骤,手机怎么做自己的网页链接?
通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】
Laravel如何实现URL美化Slug功能_Laravel使用eloquent-sluggable生成别名【方法】
怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?
Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】
如何实现建站之星域名转发设置?
Laravel如何处理CORS跨域问题_Laravel项目CORS配置与解决方案
如何挑选优质建站一级代理提升网站排名?
,南京靠谱的征婚网站?
Windows Hello人脸识别突然无法使用
长沙企业网站制作哪家好,长沙水业集团官方网站?
弹幕视频网站制作教程下载,弹幕视频网站是什么意思?
HTML5空格和margin有啥区别_空格与外边距的使用场景【说明】
Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】
公司网站制作需要多少钱,找人做公司网站需要多少钱?
如何自定义建站之星网站的导航菜单样式?
UC浏览器如何设置启动页 UC浏览器启动页设置方法
javascript日期怎么处理_如何格式化输出
猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?
Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤
Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)
HTML 中动态设置元素 name 属性的正确语法详解
如何破解联通资金短缺导致的基站建设难题?
免费网站制作appp,免费制作app哪个平台好?
Swift开发中switch语句值绑定模式
如何在腾讯云免费申请建站?
如何在宝塔面板创建新站点?
Android使用GridView实现日历的简单功能
Laravel如何操作JSON类型的数据库字段?(Eloquent示例)
EditPlus中的正则表达式 实战(1)
QQ浏览器网页版登录入口 个人中心在线进入
详解Android图表 MPAndroidChart折线图
实例解析Array和String方法
googleplay官方入口在哪里_Google Play官方商店快速入口指南
bing浏览器学术搜索入口_bing学术文献检索地址
iOS验证手机号的正则表达式

