使用const声明常量

1,206 阅读3分钟

思考中带着问题去学习:

  1. 什么是常量?他们的工作机制是什么?
  2. 学会在什么时候使用常量?

常量不能被重新赋值

一旦将某个固定的值赋值给常量,任何重新给常量赋新值的尝试都会导致错误发生

//案例-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