保捱科技网
您的当前位置:首页JavaScript中的函数调用的代码详情

JavaScript中的函数调用的代码详情

来源:保捱科技网


可能很多人在学习 JavaScript 过程中碰到过函数参数传递方式的迷惑,本着深入的精神,我给大家分享了一篇教程关于javascript中的函数调用知识,感兴趣的朋友一起学习吧

定义

可能很多人在学习 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 指向的数据

Code 2: 函数不能修改 obj

Code 3: 内部 obj 和外部 === 结果相等

所以第三段代码可能有疑问了,既然 obj 是 def 的复制,为什么 === 操作还能够为真?不是说 === 操作对于 Object 比较的是在内存中的地址么,如果是复制应该是 false 才对啊?

所以我们回到 Google V8 的源码来看这件事。

深入 Google V8

我们来看看源码里严格等于操作代码部分:

看起来应该是最后一种情况,理论上如果 def 和 obj 是不同的对象,那么应该返回 false 才对,这不是推翻了上文所述么?其实不,忽略了一件事,即 Google V8 内部在实例化一个 Object 的时候,本身就是动态实例化,而我们知道在编译型语言中如果动态实例化只能够在堆内存上,即只能够指针引用。这个结论是的证明涉及到 Local 、Handle 等 class 的实现,我觉得太麻烦,有一个简单的证明方式,即搜索源码得到所有调用 Object::StrictEquals 的地方都是直接传入而没有取地址操作。

不过有人会问,既然是值传递的变量包含 Object 的引用,理论上也能够修改 Object 才对,为什么第三段代码不能修改呢?

很简单的道理,因为我们在 Javascript 语言逻辑层次上的所谓的操作,只不过是在调用 Google V8 的实例方的法而已,根本不可能操作到这一地步(当然,潜在的 BUG 不算的 -。-)

重新定义

我觉得到这里可以给 call by sharing 重新解释一下了:

的确,传递的时候是值传递,但是内容包含了 Object 的指针,而且不能够修改这个指针,他是多个变量共享的。

另一种简单的证明

来来来,看源码

上面的是即将弃用的接口,碰巧我看到的这个版本代码包含大量的这种即将弃用的代码,看看就好。重点是第二个接口,是函数的唯一的调用的接口。里面的 Local<Value> 最终会调用 C++ 的位复制,所以可以简单的证明就是值传递。

可能是重点

别忘了,我们定义的的变量都是类似 Handle<Object> 这种形式的,所以它们之间对象才是共享的,我们所说的 Javascript 里面变量并不直接指的是 Object 的实例!!!

最后的最后

总之理解起来可能很费劲甚至有错误,但是在 Javascript 语言层次上能够确定了特性,这才是重要的。

以上所述是小编给大家介绍的Javascript中的函数调用,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

保捱科技网还为您提供以下相关内容希望对您有帮助:

JavaScript 的 Math.floor() 函数

JavaScript 的 Math.floor() 函数用于返回小于或等于给定数字的最大整数,即向下取整。功能说明:Math.floor() 会对传入的数字进行向下取整操作,返回不大于该数字的最大整数。对于正数,它会直接去掉小数部分;对于负数,它会向更小的方向取整。示例代码:Math.floor(45.95); // 返回 45Math.

JavaScript-函数

JavaScript 函数是代码复用的核心机制,具有灵活的语法和特性。以下是对关键概念的总结和示例说明:一、函数基础语法声明方式:使用 function 关键字,无需指定返回值类型和参数类型function add(a, b) { return a + b;}匿名函数:常用于函数表达式或回调var multiply = function(a, b) { return a...

javascript在函数里调用函数

window.onload=函数;这种写法,是把函数作为一个对象赋值给onload事件,这样当这个事件触发时就会执行这个函数了。而如果是:window.onload=函数();这样就是让函数立即执行,然后把运行后的返回值再赋值给onload事件,这显然是错误的。window.onload=function(){函数();} 这种写法,则是把一个匿名函数赋值...

JavaScript 的 eval() 函数详解

CodePen:JavaScript eval() 函数的基本用法 在非严格模式下,可以直接调用 eval() 函数,这在某些场景下非常有用,但请确保代码安全。非严格模式下间接引用 eval() 函数同样适用,具体实例可参考:CodePen:JavaScript 非严格模式下间接引用 eval() 函数 严格模式下,直接调用 eval() 函数可能会引发一...

javascript 中调用函数的void用法

调用的方法: foo的原型: void foo (int x,int pp[],int *n) { int i,p p=0; for (i=1;i

javascript 使表情输入到textarea 里的调用函数,求人帮我解析每行代码...

函数grin实现点击某个表情图标,就可以将表情图标翻译成代码并插入到指定的textarea中的鼠标光标停留位置。具体实现方法:var myField;if (...) { myField = document.getElementById(tagname);}else { return false;} 定义一个局部变量myField,并指向指定的textarea,如果不存在指定的textarea则退出...

javascript中this用法

情况一:纯粹的函数调用 这是函数的最通常用法,属于全局性调用,因此this就代表全局对象Global。请看下面这段代码,它的运行结果是1。function test(){ this.x = 1;alert(this.x);} test(); // 1 为了证明this就是全局对象,我对代码做一些改变:var x = 1;function test(){ alert(this.x...

JS定义函数+getM+()输出九九乘法表,“要求调用3次”

// 调用 getMultiplicationTable() 函数三次 console.log("第一次调用:");getMultiplicationTable();console.log("\n第二次调用:");getMultiplicationTable();console.log("\n第三次调用:");getMultiplicationTable();在上述代码中,`getMultiplicationTable()` 函数使用两个嵌套的 `for` 循环来...

javascript中{init();}是什么意思?

函数作用:init函数通常用于执行初始化操作,如设置默认值、配置环境或准备数据等。具体的功能取决于函数内部的实现代码。语法规范:在JavaScript中,函数调用语句末尾的分号;是一个重要的语法符号,它标志着语句的结束。如果不加分号,在某些情况下可能会引起解析错误。注意:标准的函数调用语法是函数名;,而...

如何在Javascript中将一个函数延迟一秒后执行?

javascript提供了setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式,因此延迟1秒后执行一个函数可以如下代码实现:setTimeout("fun()",1000); // fun()是自定义函数下面实例演示:打开页面后倒计时3秒,然后弹出对话框 1、HTML结构 32、javascript代码 function fun(n){if(n&gt;0){n--...

显示全文

猜你还关注