let arr = [1,2,3,4];
arr.push(5);
console.log(arr); // [1,2,3,4,5];
arr改变了,为啥eslint却说arr没有改变,建议用const
let arr = [1,2,3,4];
arr.push(5);
console.log(arr); // [1,2,3,4,5];
arr改变了,为啥eslint却说arr没有改变,建议用const
引用类型比如这里的Array,实际js中const限定的是地址不变,地址指向的值可以变化,表现出来的就是
uncaught TypeError: Assignment to constant variable.
eslint自己加戏了,可以把这条规则关掉,使用let定义
'prefer-const': 'off',
[1,2,3,4]
是一个数组,它由变量 arr
引用(也就是通过这个变量能拿到这个数组)。
如果 arr.push(5)
改变的是数组,它内部添加了一个元素 5
。
如果 arr = [1,23]
,改变的是变量,arr
现在引用了另一个数组(但原来那个数组还在,只是没有被变量引用,稍后会被垃圾回收)
const arr = ...
这里的 const 是修饰的 arr
,也就是说,这样修饰之后 arr = ...
就不行了,不能让 arr
去引用别的东西。
但数组本身还是不受约束,仍然可以进行 push()
等操作改变自身内部数据。
JS、TS里的const
代表的是引用不可变,也就是定义的变量不可重新赋值,或者说,这个变量右侧只能实行一次=
操作:
const x = [1, 2, 3, 4];
x = [5, 6, 7]; // Cannot assign to 'x' because it is a constant
x.push()
、修改对象的属性x.length
并不会修改变量的引用,是合法的操作:
const x = [1, 2, 3, 4];
x.push(5); // ok
x.length = 0; //ok
如果你要想实现类似其他语言那样,属性也不可变的话,应该使用Object.freeze
,这样在严格模式下就会报错。
'use strict';
const list = Object.freeze([1, 2, 3, 4]);
list.push(5); // Cannot add property 4, object is not extensible
'use strict';
const o = Object.freeze({ a: 1 });
o.b = 2; // Cannot add property b, object is not extensible
说简单是个简单问题,但是深究起来其实蛮奇怪的
const一般来说是声明常量,如果没记错kotlin中const真的就是引用不可变,以及引用的引用不可变,真正的常量。很不巧,JavaScript中对于const只要求了引用不可变。
const a = [1,2]
可以描述为常量a指向一个数组,这个指向不可变。粗暴的理解数组就是个容器,容器内部想怎么便就怎么变,反正指向没有变。