JavaScript参数通报体式格局

这几天碰到js参数通报体式格局的题目,深切探讨一番,将所得效果总结于此

罕见的几种通报体式格局

传值挪用(call by value)

在传值挪用中现实参数被求值,其值被绑定到函数中对应的变量上(一般是把值复制到新内存地区)。在函数返回后挪用者作用域里的曾传给函数的任何东西都不会变。

传援用挪用(call by reference)

在“传援用挪用”求值中,通报给函数的是它的
现实参数的隐式援用(即现实参数的地点)而不是实参的拷贝。一般函数能够修正这些参数(比方赋值),而且转变关于挪用者是可见的。

传同享对象挪用(call by sharing)

在传同享对象挪用中,通报给函数的是实参所指向援用对象的地点,而不是实参的地点,即通报同享对象。故在函数中修正援用对象时,实参的值也会随着变化,而如果是从新给新参赋值后,再举行任何修正都不会影响到外面的实参了。

JS中的传值体式格局

Number–传值挪用

let a = 1;
function add(val) {
  val += 1;
  console.log(`val=${val}`); // 2
}

add(a);
console.log(`a=${a}`); // 1

String–传值挪用

let a = 'hahaha';
function change(val) {
  val = 'heiheihei';
  console.log(`val=${val}`); // heiheihei
}

change(a);
console.log(`a=${a}`); // hahaha

Boolean–传值挪用

Symbol–传值挪用

let a = Symbol('prop');
function change(val) {
  val = Symbol(2);
  console.log(`val=${val.toString()}`); // Symbol(2)
}

change(a);
console.log(`a=${a.toString()}`); // Symbol(prop)

null–传值挪用

undefined–传值挪用

Object–传同享对象挪用

let obj = {
    a: 1
}
function change(obj) {
    obj.a = 2;
    console.log(obj); // {a: 2}
    obj = {
        a: 3
    }
    console.log(obj); // {a: 3}
}

change(obj);
console.log(obj); // {a: 2}

从上面的代码能够看出,在函数中对参数所指向的对象举行修正时会影响到外面的实参,但对函数参数从新赋值时,不会影响到实参,故js援用范例的传值体式格局为call by sharing

深切探讨

变量存储体式格局

《JavaScript参数通报体式格局》

C#中范例有两种:值范例和援用范例,它们之间的却别在于现实数据存储的位置(如上图)。值范例的变量和现实数据都存储在客栈中;而援用范例则只要变量存储在客栈中,变量存储着现实数据的地点,现实数据存储在与地点相对应的托管堆中。

C#中的值通报

  • 一般情况下,值范例按值通报
  • 一般情况下,运用范例按同享对象的体式格局通报(call by sharing),但string范例除外(因为string的不可变性,它是按值通报的)
  • 经由过程运用ref或out关键字,值范例和援用范例都能够按援用通报

总结

综上所述(证明题2333),值通报和援用通报的参数范例既能够是值范例又能够是援用范例,然则call by sharing的参数范例只能是援用范例。

个人明白:JS中,null赋值的变量时对象,然则,变量指向的援用地点为空,故在函数中修正参数的值,对实参不会又任何影响,所所以按值通报。string范例应当跟C#按值通报的缘由一致。

参考:
维基百科
JS中的值是按值通报,照样按援用通报呢
《Learning hard C#进修笔记》第10章

    原文作者:feipeng123s
    原文地址: https://segmentfault.com/a/1190000016091606
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞