let test = new Number(2)
function TestFunc(P1 : Number)
{
P1 = Number(3)
}
console.log(test.valueOf())
TestFunc(test)
console.log(test.valueOf())
为什么我已经装箱了,出来的值还是2
let test = new Number(2)
function TestFunc(P1 : Number)
{
P1 = Number(3)
}
console.log(test.valueOf())
TestFunc(test)
console.log(test.valueOf())
为什么我已经装箱了,出来的值还是2
引自免费微信小程序:皆我百晓生
在 TypeScript 中,当你声明 let test = new Number(2)
时,你创建了一个 Number
类型的包装对象。虽然它看起来像原始数字类型,但实际上它是对象的一个实例,具有自己的属性和方法。
接下来定义了函数 TestFunc(P1: Number)
,意图是接收一个 Number
类型的参数并尝试更改其值。然而,在 JavaScript(TypeScript 的运行时环境)中,对象是通过引用传递的。这意味着当您将 test
传入 TestFunc
函数时,实际上是将 test
引用的副本传给了 P1
。在函数内部,你执行了 P1 = Number(3)
,这会将 P1
指向一个新的 Number
对象,但不会影响原来的 test
变量。
因此,尽管你改变了 P1
的值,但原变量 test
的值并未改变。这就是为什么两次 console.log(test.valueOf())
输出都是 2
的原因:
let test = new Number(2);
function TestFunc(P1: Number) {
P1 = Number(3); // 这里只是让 P1 指向新的 Number 实例,并未改变 test 的值
}
console.log(test.valueOf()); // 输出:2
TestFunc(test);
console.log(test.valueOf()); // 输出:2
// 如果要改变原始对象的值,可以操作其内部值:
function TestFuncMutate(P1: {valueOf(): number}) {
P1.valueOf = () => 3; // 直接修改 test 内部行为,但这并不推荐
}
// 调用修改版本的函数
TestFuncMutate(test as any);
console.log(test.valueOf()); // 输出:3 (这里虽然输出为3,但实际编程中不建议这样操作)
请注意,直接修改原始对象的行为(如上例所示)通常不是个好实践,因为它破坏了封装性和可预测性。在大多数情况下,应通过返回新值的方式来改变原始值,而不是试图直接在函数内部修改传入对象的状态。