Javascript是否通过引用?

Javascript是通过引用还是传递值? 这里是一个来自Javascript的例子:好的部分 。 我非常困惑my的矩形函数的参数。 它实际上是undefined ,并在函数内重新定义。 没有原始参考。 如果从函数参数中删除它,内部区域function将无法访问它。

这是封闭吗? 但是没有函数返回。

 var shape = function (config) { var that = {}; that.name = config.name || ""; that.area = function () { return 0; }; return that; }; var rectangle = function (config, my) { my = my || {}; my.l = config.length || 1; my.w = config.width || 1; var that = shape(config); that.area = function () { return my.l * my.w; }; return that; }; myShape = shape({ name: "Unhnown" }); myRec = rectangle({ name: "Rectangle", length: 4, width: 6 }); console.log(myShape.name + " area is " + myShape.area() + " " + myRec.name + " area is " + myRec.area()); 

基元通过值传递,对象通过“引用副本”传递。

具体来说,当你传递一个对象(或数组)时,你(无形地)传递了对该对象的引用,并且可以修改该对象的内容 ,但是如果你试图覆盖引用,它不会影响副本调用者所持有的引用 – 即引用本身是按值传递的:

 function replace(ref) { ref = {}; // this code does _not_ affect the object passed } function update(ref) { ref.key = 'newvalue'; // this code _does_ affect the _contents_ of the object } var a = { key: 'value' }; replace(a); // a still has its original value - it's unmodfied update(a); // the _contents_ of 'a' are changed 

与C ++相比,更改引用types可以完全替代调用者传递的对象:

 void replace(mytype& ref) { ref = *new mytype(); // ignoring the memory leak for the purposes of this example } mytype a; replace(a); // a is now a _different_ object 

像这样想:

每当你在ECMAscript中创build一个对象的时候,这个对象就形成了一个神秘的ECMAscript普遍的地方 ,没有人能够得到。 所有你回来的是在这个神秘的地方对这个对象的引用

 var obj = { }; 

即使obj只是对象的一个​​引用(它位于那个特别美妙的地方),因此,你只能通过这个引用 。 实际上,任何访问obj的代码都会修改远处的对象

我的2美分….这是不相关的是否通过参考或价值传递参数。 真正重要的是赋值与变异。

我在这里写了一个更长,更详细的解释( JavaScript是通过引用还是按值传递的语言? )

当你传递任何东西(不pipe是一个对象还是一个原语)时,所有的javascript都是在函数内部分配一个新variables,就像使用等号(=)

这个参数在函数内的行为方式与使用等号分配一个新variables的行为完全相同。以这些简单的例子为例。

 var myString = 'Test string 1'; // Assignment - A link to the same place as myString var sameString = myString; // If I change sameString, it will not modify myString, // it just re-assigns it to a whole new string sameString = 'New string'; console.log(myString); // logs 'Test string 1'; console.log(sameString); // logs 'New string'; 

如果我将myString作为parameter passing给一个函数,就像我简单地将它分配给一个新的variables一样。 现在,让我们做同样的事情,但是用一个函数来代替简单的赋值

 function myFunc(sameString) { // Re assignment.. again, it will not modify myString sameString = 'New string'; } var myString = 'Test string 1'; // This behaves the same as if we said sameString = myString myFunc(myString); console.log(myString); // Again, logs 'Test string 1'; 

当你将对象传递给一个函数的时候,你可以修改对象的唯一原因是你不重新分配对象,而是可以改变或者改变对象……同样,它的工作原理也是一样的。

 var myObject = { name: 'Joe'; } // Assignment - We simply link to the same object var sameObject = myObject; // This time, we can mutate it. So a change to myObject affects sameObject and visa versa myObject.name = 'Jack'; console.log(sameObject.name); // Logs 'Jack' sameObject.name = 'Jill'; console.log(myObject.name); // Logs 'Jill' // If we re-assign it, the link is lost sameObject = { name: 'Howard' }; console.log(myObject.name); // Logs 'Jill' 

如果我将myObject作为parameter passing给一个函数,就像我简单地将它分配给一个新的variables一样。 再一次,具有完全相同的行为,但function相同的东西。

 function myFunc(sameObject) { // We mutate the object, so the myObject gets the change too... just like before. sameObject.name = 'Jill'; // But, if we re-assign it, the link is lost sameObject = { name: 'Howard' }; } var myObject = { name: 'Joe'; } // This behaves the same as if we said sameObject = myObject; myFunc(myObject); console.log(myObject.name); // Logs 'Jill' 

每次将一个variables传递给一个函数,就像是使用了相等(=)符号一样,无论参数的名字是“赋值”。

永远记住等号(=)意味着分配。 并且传递参数给函数也意味着赋值。 它们是相同的,两个variables的连接方式完全相同。

修改variables的唯一时间影响不同的variables是基础对象发生了变化。

在对象和基元之间进行区分没有任何意义,因为它的工作原理与没有函数的方式一样,只是使用等号来分配一个新的variables。

与C一样,最终,所有的东西都是通过价值传递的。 与C不同的是,你实际上不能备份和传递一个variables的位置,因为它没有指针的引用。

它所具有的引用全部是对象而不是variables。 有几种方法可以达到同样的结果,但是必须手工完成,而不仅仅是在呼叫或声明站点添加关键字。

JavaScript是通过价值。 对于基元,基元的值被传递。 对于对象,传递对象的引用“值”。

对象示例:

 var f1 = function(inputObject){ inputObject.a=2; } var f2 = function(){ var inputObject={"a":1}; f1(inputObject); console.log(inputObject.a); } 

调用f2导致打印出“a”值为2而不是1,因为参考被传递并且参考中的“a”值被更新。

原始示例:

 var f1 = function(a){ a=2; } var f2 = function(){ var a =1; f1(a); console.log(a); } 

调用f2导致打印出“a”值为1。

实际上,Alnitak是正确的,并使其易于理解,但最终在JavaScript中,一切都通过价值传递。

对象的“价值”是什么? 这是对象引用。

当你传入一个对象时,你会得到这个值的一个副本(因此Alnitak描述的“引用副本”)。 如果更改此值,则不会更改原始对象,而是更改该引用的副本。

“全局”JavaScriptvariables是窗口对象的成员。 您可以作为窗口对象的成员访问引用。

 var v = "initialized"; function byref(ref) { window[ref] = "changed by ref"; } byref((function(){for(r in window){if(window[r]===v){return(r);}}})()); // could also be called like... byref('v'); console.log(v); // outputs changed by ref 

请注意,上面的例子不适用于函数中声明的variables。

函数参数是通过值或共享传递的,但绝对不能在Javascript中引用!

呼叫按值

原始types按值传递:

 var num = 123, str = "foo"; function f(num, str) { num += 1; str += "bar"; console.log("inside of f:", num, str); } f(num, str); console.log("outside of f:", num, str); 

为了创build一个简单的例子,使用const …

 const myRef = { foo: 'bar' }; const myVal = true; function passes(r, v) { r.foo = 'baz'; v = false; } passes(myRef, myVal); console.log(myRef, myVal); // Object {foo: "baz"} true