基元类型(数字、字符串等)是通过值传递的,但对象是未知的,因为它们既可以通过值传递(如果我们认为持有对象的变量实际上是对对象的引用),也可以通过引用传递(当我们认为对象的变量持有对象本身)。
虽然最后这并不重要,但我想知道通过约定来表达论点的正确方式是什么。是否有JavaScript规范的摘录,该规范定义了与此相关的语义?
基元类型(数字、字符串等)是通过值传递的,但对象是未知的,因为它们既可以通过值传递(如果我们认为持有对象的变量实际上是对对象的引用),也可以通过引用传递(当我们认为对象的变量持有对象本身)。
虽然最后这并不重要,但我想知道通过约定来表达论点的正确方式是什么。是否有JavaScript规范的摘录,该规范定义了与此相关的语义?
当前回答
我在AirBNB风格指南中找到了最简洁的解释:
基本体:访问基本体类型时,直接处理其价值一串数字布尔型无效的未定义
例如。:
var foo = 1,
bar = foo;
bar = 9;
console.log(foo, bar); // => 1, 9
复杂:访问复杂类型时,需要处理对其值的引用对象大堆作用
例如。:
var foo = [1, 2],
bar = foo;
bar[0] = 9;
console.log(foo[0], bar[0]); // => 9, 9
也就是说,基本类型是通过值传递的,复杂类型是通过引用传递的。
其他回答
一切都是通过价值传递的。
基本类型按值传递(即,实际变量值的新副本传递给函数)。
复杂类型(对象)作为“对象指针”传递。因此,您传递的实际内容是一个指针,它是按值传递的(它是一个地址,一个像任何其他值一样的数值)。显然,如果您试图在函数内修改对象的属性,那么即使在该函数外,修改也会反映出来。这是因为您通过指向属性唯一副本的指针访问属性。
这里的混淆出现在“通过值传递指针”和“通过引用传递对象”上。
这里有一些关于JavaScript中使用术语“通过引用传递”的讨论,但要回答您的问题:
对象通过引用自动传递,无需特别声明
(摘自上述文章。)
嗯,这是关于“性能”和“速度”的,在编程语言中,简单地说就是“内存管理”。
在javascript中,我们可以将值放在两层:type1对象和type2所有其他类型的值,如字符串和布尔值等
如果你把记忆想象成下面的方块,其中每个方块中只能保存一个type2值:
每个type2值(绿色)是一个正方形,而type1值(蓝色)是它们的一组:
重点是,如果你想指示一个type2值,地址是很简单的,但如果你想对type1值做同样的事情,那根本不容易!:
在一个更复杂的故事中:
所以这里的参考资料可以拯救我们:
虽然这里的绿色箭头是一个典型变量,但紫色箭头是对象变量,所以因为绿色箭头(典型变量)只有一个任务(这表示一个典型值),所以我们不需要将它的值与它分开,所以我们将绿色箭头与它的值一起移动到任何位置,在所有赋值、函数等中。。。
但我们不能用紫色箭头做同样的事情,我们可能想把“约翰”牢房搬到这里或其他很多事情。。。,所以紫色的箭头会固定在它的位置上,而分配给它的典型箭头会移动。。。
一个非常令人困惑的情况是,您无法意识到引用的变量是如何变化的,让我们来看一个非常好的例子:
let arr = [1, 2, 3, 4, 5]; //arr is an object now and a purple arrow is indicating it
let obj2 = arr; // now, obj2 is another purple arrow that is indicating the value of arr obj
let obj3 = ['a', 'b', 'c'];
obj2.push(6); // first pic below - making a new hand for the blue circle to point the 6
//obj2 = [1, 2, 3, 4, 5, 6]
//arr = [1, 2, 3, 4, 5, 6]
//we changed the blue circle object value (type1-value) and due to arr and obj2 are indicating that so both of them changed
obj2 = obj3; //next pic below - changing the direction of obj2 array from blue circle to orange circle so obj2 is no more [1,2,3,4,5,6] and it's no more about changing anything in it but we completely changed its direction and now obj2 is pointing to obj3
//obj2 = ['a', 'b', 'c'];
//obj3 = ['a', 'b', 'c'];
变量不“保存”对象;它有一个参考。您可以将该引用分配给另一个变量,现在两者都引用同一个对象。它总是按值传递(即使该值是引用…)。
无法更改作为参数传递的变量所持有的值,如果JavaScript支持通过引用传递,这是可能的。
我发现Undercore.js库的extend方法非常有用,当我想将一个对象作为一个参数传递时,它可以被修改或完全替换。
function replaceOrModify(aObj) {
if (modify) {
aObj.setNewValue('foo');
} else {
var newObj = new MyObject();
// _.extend(destination, *sources)
_.extend(newObj, aObj);
}
}