我想将一个变量传递给一个函数并让该函数改变该值。
我知道我可以将其作为一个对象来执行此操作,但我想知道是否有一些我还没有想到的方法可以做到这一点。
这就是我想要做的,但它当然不能按照我想要的方式进行:
function test1(vari) {
vari = 2;
}
var myvar1 = 1;
test1(myvar1);
console.log(myvar1); //1
这可行,但我并不真正想将所有变量都变成对象:
function test2(vari) {
vari.val = 2;
}
var myvar2 = { val: 1 };
test2(myvar2);
console.log(myvar2.val); //2
这也有效,但不是一个可接受的解决方案:
function test3(vari) {
eval(vari + ' = 2;');
}
var myvar3 = 1;
test3('myvar3');
console.log(myvar3); //2
还有比这些更好的选择吗?
更新
我想做的一个更好的例子:
function test5(vari, onblur) {
document.querySelector('body').innerHTML += `<input id="ctl_${vari}" type="text" value="${vari}">`;
el = document.getElementById(`ctl_${vari}`);
el.addEventListener('blur', function(e) {
vari = e.target.value; //Doesn't update original variable
onblur(e);
});
return el;
}
var myvar5 = 'test';
var ele = test5(
myvar5,
function(e) {
//Could set myvar5 = e.target.value but not wanting to do this for every single field
console.log(myvar5);
}
);
9
最佳答案
4
就像,你不能在 JavaScript 中传递引用。传递给函数的所有参数都是按值传递的。对象也是如此。虽然你可以改变作为参数传递的对象,但你不能重新分配它(使其成为按值传递)。有关详细信息,请参阅:和(也适用于 JavaScript)。
您可以使用数组返回多个值:
function test(a, b) {
return [a + b, a - b];
}
let a = 5, b = 2;
[a, b] = test(a, b);
的最终值a
是7
且b
是3
。
请注意,后面的分号let a = 5, b = 2;
是必需的,否则它将被执行,let a = 5, b = 2[a, b] = test(a, b);
在这种情况下会导致“未捕获的 ReferenceError:在初始化之前无法访问词法声明‘b’”。
但是在您的特定场景中,您可以简单地将所需的值onblur
作为参数传递给函数,以避免myvar5 = e.target.value
在每个函数定义中都这样做。
function test5(vari, onblur) {
document.querySelector('body').innerHTML += `<input id="ctl_${vari}" type="text" value="${vari}">`;
const el = document.getElementById(`ctl_${vari}`);
el.addEventListener('blur', function(e) {
onblur(e, e.target.value);
});
return el;
}
// best matching the question code
var myvar5 = 'test';
var ele = test5(myvar5, function(e, myvar5) {
console.log(myvar5);
});
// probably preferable given the current question code
var ele = test5('test', function(e, value) {
console.log(value);
});
1
-
看起来我将要处理模糊处理程序中的值的更新,因为这是最干净的方法。
–
|
这可能不是您想要的,但也许可以尝试以下方法:
function test1(vari) {
return vari += 2;
}
var myvar1 = test1(myvar1);
console.log(myvar1);
3
-
我的例子只是简化的例子,但在我的例子中我不能使用返回。
– -
1您的意思是,对于您的项目,您不能使用 return ,因为它不合适,或者当您尝试使用它时出现错误?
– -
它不合适。
–
|
在 JS 中,只有对象元素通过引用传递。
所以不要指望用一个简单的变量就能做到这一点。
但是,由于所有变量都属于窗口对象,所以
您可以这样对待它,但这是本世纪最糟糕的想法。
function fx(varName)
{
window[varName]++;
}
var myVar = 5;
fx('myVar');
console.log( myVar ); // 6
4
-
2“对象是通过引用传递的。 ” – 不,不是。它们可能是引用值,但它们仍然是通过值传递的。
– -
@Bergi 对的,我重新表述了这句话。
–
-
第二糟糕?
eval
会更糟糕,对吧?
– -
1我没有想到这个选项,虽然这不是一个好的做法,但它比 eval 更好,所以谢谢你的回答。应该注意,这只会获取全局变量。
–
|
在您的例子中,我假设该参数vari
是一个原始值。以下是一些修复它的方法:
- 用对象包装值
- 不将其用作参数(将其从函数声明中删除)
number
像和 这样的原始值string
是通过值传递的
其他人喜欢object
并被array
“引用副本”传递
以下是一些示例:
let primitiveVar = 1;
let function1 = (primitiveParam) => {
primitiveParam = 3;
};
// not work for primitive values
function1(primitiveVar);
console.log(primitiveVar); // 1
let primitiveVar2 = 1;
let function2 = (primitiveParam) => {
return primitiveParam + 3;
};
// due to primitive value immutability we need to reassign
primitiveVar2 = function2(primitiveVar2);
console.log(primitiveVar2); // 4
let objectVar = {
val: 1,
};
let function3 = (objectParam) => {
// objectParam has the same ref as objectVar
objectParam.val = 2;
};
function3(objectVar);
console.log(objectVar.val); // 2
let objectVar2 = {
val: 1,
};
let function4 = (objectParam) => {
// objectParam ref is now point to a different object
objectParam = { val: 3 };
};
function4(objectVar2);
console.log(objectVar2.val); // 1
工作场地:
1
-
2“其他的,比如对象和数组,都是通过引用传递的” – 不,它们不是。它们是通过值传递的引用值。
–
|
–
–
myVar = myFunc(myVar);
地方有什么问题?myFunc()
–
–
–
|