如何正确传递 Javascript 属性,以便它们可以被函数修改

How to pass Javascript properties correctly such that they can be modified by a function

我明白 JavaScript 对象,包括数组,自动通过引用传递,所以我有这样的东西:

class Thing {
    constructor( ) {
        this.letters = [ "A", "B" ];
        this.numbers = [ 1, 2, 3 ];

        this.change( this.letters, this.numbers );
    }

    change( _letters, _numbers ) {
        let l = _letters;
        let n = _numbers;

        l = [ ];
        n = 6;
    }
}

var t = new Thing( );
console.log( t );

日志请求显示 Thing 的属性没有变化。然而,在我无法识别的不同条件下,我不小心修改了函数内部传递的参数,并且不得不使用类似 n = Array.from( _numbers ) 的东西来避免修改源代码 属性。 有人可以解释发生了什么,为什么?

我想通过引用传递对象属性,这样我就可以在单个函数调用中修改多个相关的 属性,从而保留 return 值用于调试目的。

谢谢。

问题是范围界定。当您使用 let 声明时,声明的作用域为函数 change 并且您还在此处重新分配块作用域变量:

l = [ ];
n = 6;

如果您想更改 class 属性,您可以这样做:

change(_letters, _numbers) {
    this.letters = _letters; // `this` scoped to class
    this.numbers = _numbers; // `this` scoped to class
  }

看例子:

// simple demo start
let numbers = [1, 2, 3];

let n = numbers;
n.push(4)
console.info(n, typeof n);

n = 6; // reassign n
console.info(n, typeof n, numbers);
// simple demo end

// refactored class
class Thing {
  constructor() {
    this.letters = ["A", "B"];
    this.numbers = [1, 2, 3];

    this.change(this.letters, this.numbers);
  }

  change(_letters, _numbers) {
    let l = _letters; // `let` is scoped to `change()`
    let n = _numbers; // `let` is scoped to `change()`

    l = []; // only changes scoped l
    n = 6; // only changes scoped n
  }

  changeFix(_letters, _numbers) {
    this.letters = _letters; // `this` scoped to class
    this.numbers = _numbers; // `this` scoped to class
  }
}

var t = new Thing();
console.log(t);

t.change(['C'], [4]);
console.info(t);

t.changeFix(['C'], [4]);
console.info(t);