思考中带着问题去学习:
- 什么是常量?他们的工作机制是什么?
- 学会在什么时候使用常量?
常量不能被重新赋值
一旦将某个固定的值赋值给常量,任何重新给常量赋新值的尝试都会导致错误发生
//案例-1
const NORMAL_NUMBER=123; //定义一个常量
NORMAL_NUMBER=12; //尝试重新赋值
console.log(NORMAL_NUMBER); // 报错
复制代码
以上代码会让我们的思维变得很混乱,我们脑海中会认为这是一成不变的常量,常量是不变的,所以我们不能给它重新赋值,但是你会发现,这里所说的"不变"和"不能重新赋值"有什么区别呢?
//案例-2
const normalObject={}; //定义一个常量
normalObject.propertyOne='this is property of One';
normalObject.propertyOne='this is a new property'; //重新给对象的属性赋值
console.log(normalObject.propertyOne); //'this is a new property';
复制代码
此时输出的是对象属性propertyOne重新赋值后的属性值
//案例-3
normalObject={newProperty:'eastboat'} //尝试重新赋值一个新的对象,将属性定义为newProperty
console.log(normalObject); //TypeError: Assignment to constant variable.
复制代码
由上述可知,重新赋值与变量的绑定有关,也就是将名称绑定到某条数据上,如上案例1,NORMAL_NUMBER变量是被绑定到了数据123上面,所以重新赋值就会报错;而常量是不可变的,这里的不变是属于绑定时所含的实际数据的属性,如上案例2和3所示,常量绑定的是一个对象,我们都知道js中字符串,数组等都是不可变,但是对象是可变的(引用类型),所以创建后的对象我们将可变的值(属性)赋给它。如果将常量重新定义为一个新的对象(指向一个新的地址),此时就会报错,所以我们只能修改对象数据本身的值,而不能直接修改常量本身。
思考下列代码输出什么?
const num=0;
num++;
console.log(num)
复制代码
现在我们再看一个案例:
let strA='hello';
let strB=strA;
strB += ‘,world’;
console.log(strA) //hello
console.log(strB) //hello,world
复制代码
这也就是不能对常量使用运算符
+=
的原因,因为有新的值产生,那么此时你可以再次思考下面代码发生了什么?
const strA='hello';
const strB=strA.concat(',world!')
复制代码
有时候直觉让我们觉得报错,但是请记住concat是对字符串进行的操作,不改变现存的字符串或对含有此字符串的变量进行重新赋值,所以此时strB得到的是一个新的字符串
何时使用常量?
//最常见使用常量创建标识
const ADD_PERSON='ADD_PERSON';
const DEL_PERSON='DEL_PERSON';
let personArr=[];
function actionHandler(action){
if(action.type==ADD_PERSON){
personArr.push(action.person)
}else if(action.type==DEL_PERSON){
personArr.splice(personArr.indexOf(action.person),1)
}
}
复制代码
如果上面的personArr
不会被重新赋值,我们是否可以使用const来声明?
const ADD_PERSON='ADD_PERSON';
const DEL_PERSON='DEL_PERSON';
const personArr=[];
function actionHandler(action){
if(action.type==ADD_PERSON){
personArr.push(action.person)
}else if(action.type==DEL_PERSON){
personArr.splice(personArr.indexOf(action.person),1)
}
}
复制代码
设想:我现在需要一个动作来清空列表,可能我们本能的会想到,使用item=[]
来清空数组,但是上面我们使用的是const
声明的常量,常量是不能被重新赋值的
const ADD_PERSON='ADD_PERSON';
const DEL_PERSON='DEL_PERSON';
const DEL_ALL_PERSON='DEL_ALL_PERSON'; //增加清空数组行为
const personArr=[];
function actionHandler(action){
if(action.type==ADD_PERSON){
personArr.push(action.person)
}else if(action.type==DEL_PERSON){
personArr.splice(personArr.indexOf(action.person),1)
}else if(action.type==DEL_ALL_PERSON){
personArr.splice(0,personArr.length) //清空数组
}
}
复制代码
最后看一个案例
//常量与绑定值有关,不与所绑定值里面的数值有关,函数仅仅是返回数值,而不是绑定的值
//所以新的let绑定的值可以安全的进行重新赋值
function getValue(){
const val=123;
return val
}
let myVal=getValue();
console.log(myVal+=1); //124
复制代码