JavaScript是否通过引用传递?
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 ()
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的人来说,这很容易。