javascript php 传參,JavaScript参数传递图解教程

参数到底如何传递?本次尝试通过流程图的形式并结合两个例子来重新理解一下JavaScript中的参数传递,希望能帮助到大家。

借用红宝书的一句话:ECMAScript中所有函数的参数都是按值传递的

这个值如果是简单类型,那么就是其本身。如果是引用类型也就是对象传递的就是指向这个对象的地址。故我们可以认为参数传递全部都是值传递,那么具体怎么理解呢?看下例子:

第一个例子var obj = {

n: 1

};

function foo(data) {

data = 2;

console.log(data); //2

}

foo(obj);

console.log(obj.n) // 1

先不说为什么原因,我们就通过画图的方式来走一遍流程,我相信应该就能理解其中的参数传递了。切记传递引用类型传递的是指针!

e5b3e235766c46a318b1b0f97c5ac8f5.png

首先执行var obj = {n: 1};,可以看作在栈的001地址中存入了一个指向{n:1}的指针*p

d24c2adabed7d1a260495b56f4b38668.png

接下来为声明function foo此时会创建函数执行上下文,产生一个变量对象,其中声明了形参data,由于函数没有执行,当前值为undefined。我们记data地址为022。关于更多变量对象的知识可以参考冴羽老师的这篇JavaScript深入之变量对象,本文不深入研究关于AO相关,你只需要知道在声明这个函数的时候里面的形参已经被创建出来了。

ebf07a862cf955a6c2517f5601450a0c.png

执行foo(obj)其中会进行参数传递,其中将obj中存储的*p拷贝给处在022地址的data,那么此时它们就指向了同一个对象,如果某一个变量更改了n的值,另一个变量中n的值也会更改,因为其中保存的是指针。

6bad130c8036b050dcdebc73fbc2eb9e.png

进入函数内部,顺序执行data = 2;此时002地址存储了基本类型值,则直接存储在栈中,从而与堆中的{n:1}失去了联系。从而打印console.log(data) // 2,最后发现初始开辟的{n:1}对象没有过更改,故而console.log(obj.n) // 1仍然打印1。

第二个例子var obj = {n:1};

(function(obj){

console.log(obj.n); //1

obj.n=3;

var obj = {n:2};

console.log(obj.n) //2

})(obj);

console.log(obj.n) //3

整体来看这个例子中出现了同名覆盖的问题。不太了解代码如何执行的流程,可能会因为同名的关系而有些混乱,不过没关系。只要按照上一个例子的流程图中的执行过程,一定可以得出正确的结果。

b046ee593f45acc3a9bc10f467fb85fd.png

声明变量obj,地址为011其中存入指向{n:1}的指针*p

9048a39d0fc236036757d243d1fff394.png

声明函数,虽然同为obj变量名,但是形参obj为AO中的属性,不会与全局造成覆盖,其拥有新的地址记作022,在未执行前其值为undefined。

d4c93e059c0fb057ca5fffeb79655a73.png

函数立即执行,此时将全局obj赋值给形参obj,我们忽略这个重复命名的问题,其实就是将011中的 指针*p拷贝了一份给了022。同时执行第一个console.log(obj.n)结果即为1。

a6ea3ced19644ee9da60920d9a8486c4.png

执行obj.n=3,此时为函数的形参即022中的obj来改变了对象内n的值。

0eb3c7a825ca80c07e2acb9d0fc38191.png

最关键的一步:var obj = {n:2};由于对象命名的关系可能很多童鞋就会有点懵,但依然按照同样的方式来分析即可,由于使用了var那么就是新声明一个对象,从而会在栈中压入新的地址记作033,其中存入了新的指针指向了新的对象{n:2}。从而之后打印的console.log(obj.n)结果则应是新开辟的对象中的n的值。

最后打印console.log(obj.n) //3很显然,全局的对象有过一次更改其值为3。

小结

至此我们走完了上述两段代码涉及变量的所有“心路历程”,由于作者不是科班出身,这个图中对于堆栈以及变量重名的描述可能不是非常的准确,有差错的地方还望不吝赐教~重点是能理解我希望表达的意思就好。总的来说关键点就在于传参的过程中存在一次值的拷贝,同时如果赋值对象是引用类型传入的是指针,明白这两点之后再加上之前流程图的分析相信再遇到类似的问题都可以有较为一致的思路了。

相关推荐:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值