JavaScript是否通过引用传递?

JavaScript是否通过引用传递?,javascript,reference,pass-by-reference,pass-by-value,Javascript,Reference,Pass By Reference,Pass By Value,JavaScript是通过引用传递还是通过值传递 下面是一个来自中国的例子。我对矩形函数的my参数感到非常困惑。它实际上是未定义的,并在函数内部重新定义。没有原始参考。如果我将其从函数参数中删除,则内部区域函数将无法访问它 结束了吗?但没有返回任何函数 var shape = function (config) { var that = {}; that.name = config.name || ""; that.area = function ()

JavaScript是通过引用传递还是通过值传递

下面是一个来自中国的例子。我对矩形函数的
my
参数感到非常困惑。它实际上是未定义的,并在函数内部重新定义。没有原始参考。如果我将其从函数参数中删除,则内部区域函数将无法访问它

结束了吗?但没有返回任何函数

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
你可以这样想:

每当你在ECMAscript中创建一个对象时,这个对象都是在一个神秘的ECMAscript通用场所中形成的,在那里没有人能够得到它。你得到的只是一个对这个神秘地方的物体的引用

var obj = { };

即使是
obj
也只是对对象(位于那个特别奇妙的地方)的引用,因此,您只能传递这个引用。实际上,任何访问obj的代码都会修改非常非常远的对象。

与C一样,最终所有内容都是按值传递的。与C不同,您不能实际备份和传递变量的位置,因为它没有指针,只有引用

它所引用的都是对象,而不是变量。有几种方法可以实现相同的结果,但它们必须手工完成,而不仅仅是在调用或声明站点添加关键字。

实际上,这使它易于理解,但最终在JavaScript中,一切都是按值传递的

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


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

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。

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

var v = "initialized";

function byref(ref) {
  window[ref] = "changed by ref";
}

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

请注意,上述示例不适用于函数中声明的变量。

My two Cent。。。。JavaScript是通过引用还是通过值传递参数是无关紧要的。真正重要的是分配与变异

我写了一篇更长的

当您传递任何内容(无论是对象还是原语)时,JavaScript所做的只是在函数内部分配一个新变量。。。就像使用等号一样(
=

该参数在函数中的行为与仅使用等号指定新变量时的行为完全相同。。。以这些简单的例子为例

var myString='teststring1';
//赋值-指向myString所在位置的链接
var sameString=myString;
//如果我更改sameString,它将不会修改myString,
//它只是将其重新分配给一个全新的字符串
sameString='newstring';
console.log(myString);//记录“测试字符串1”;

console.log(sameString);//记录“新字符串”函数参数可以通过值传递,也可以通过共享传递,但在JavaScript中决不能通过引用传递

按值调用 基元类型按值传递:

var num=123,str=“foo”; 函数f(num,str){ num+=1; str+=“bar”; log(“f的内部:”,num,str); } f(num,str);
log(“在f之外:”,num,str)为了创建一个使用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

如果没有纯粹性,我认为在JavaScript中通过引用模拟标量参数的最佳方法是使用object,就像前面的回答所说的那样

但是,我做的有点不同:

我在函数调用中进行了对象赋值,因此可以看到函数调用附近的引用参数。它增加了源代码的可读性

var r;

funcWithRefScalars(r = {amount:200, message:null} );
console.log(r.amount + " - " + r.message);


function funcWithRefScalars(o) {  // o(amount, message)
  o.amount  *= 1.2;
  o.message = "20% increase";
}
在函数声明中,我像注释一样放置属性,原因非常相同:可读性

var r;

funcWithRefScalars(r = {amount:200, message:null} );
console.log(r.amount + " - " + r.message);


function funcWithRefScalars(o) {  // o(amount, message)
  o.amount  *= 1.2;
  o.message = "20% increase";
}
在上面的示例中,
null
清楚地指示输出参考参数

出口:

240 - 20% Increase
在客户端,
console.log
应替换为
alert

★ ★ ★

另一种更具可读性的方法:

var amount, message;

funcWithRefScalars(amount = [200], message = [null] );
console.log(amount[0] + " - " + message[0]);

function funcWithRefScalars(amount, message) {  // o(amount, message)
   amount[0]  *= 1.2;
   message[0] = "20% increase";
}

在这里,您甚至不需要创建新的虚拟名称,如上面的
r

原语是按值传递的。但如果您只需要读取primitve的值(调用函数时该值未知),则可以传递函数,该函数在需要时检索该值

function test(value) {
  console.log('retrieve value');
  console.log(value());
}

// call the function like this
var value = 1;
test(() => value);

在人们试图证明这一点的例子中,我看不到按引用传递。我只看到通过值传递

对于包含对象引用的变量,引用是这些变量的值,因此传递引用,然后传递值

在这样的声明中,

var a = {
  b: "foo",
  c: "bar"
};
“a”的值不是对象,而是(目前为止仅限于)对它的引用。换言之,对象不在变量
a
中-是对它的引用。我认为这对于主要只熟悉JavaScript的程序员来说似乎很困难。但对于同样懂Java、C和C的人来说,这很容易。