不要总是使用var定义了,js中var、let、const的区别

in js with 0 comment

js种的var

var是js的一个关键字,它是用来声明变量的。

声明一个变量有两种方式:

var num1 = 1;

num2 = 2;
// delete num1;  无法删除
// delete num2;  删除
function model(){
var num1 = 1; // 本地变量
num2 = 2;     // window的属性
// 匿名函数
(function(){
var num = 1; // 本地变量
num1 = 2; // 继承作用域(闭包)
 num3 = 3; // window的属性
}())

}

变量提升

JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行的运行,这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升

    console.log(a);

    var a=1;

以上的语句不会报错,只是提示undefined。实际的运行过程:

    var a;

    console.log(a);

a=1;表示变量a已声明,但还未赋值。但是变量提升只对var命令声明的变量有效,如果一个变量不是var变量声明的,就不会发生变量提升,例如以下实例:

 console.log(aa);

    aa=1;以上代码将会报错aa is not defined

与普通变量一样,js中的function也可看做变量,也存在变量提升的情况:

a();

function a(){

console.log(1);

}

表面上,上面的代码好像在声明之前就调用了函数a。但是实际上,由于变量提升,函数a定义部分被提升到了代码头部,也就是在调用之前已经声明了。但是,如果采用赋值语句定义函数,JavaScript就会报错:

a();

var a=function(){

console.log(1);

}//会报 a is not a function

因为实际运行过程:

var a;

a();

a=function(){

console.log(1);

}//这时候a是个变量,并非function

js中的const

在我们使用const声明常量。
onst实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。

但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

const foo = {};

// 为 foo 添加一个属性,可以成功
foo.prop = 123;

// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only

const a = [];
a.push('Hello'); // 可执行
a.length = 0;    // 可执行
a = ['Dave'];    // 报错
const foo = Object.freeze({});

// 常规模式时,下面一行不起作用;
// 严格模式时,该行会报错
foo.prop = 123;

var constantize = (obj) => {
  Object.freeze(obj);
  Object.keys(obj).forEach( (key, i) => {
    if ( typeof obj[key] === 'object' ) {
      constantize( obj[key] );
    }
  });
};

所以在使用复合类型的时候,尽量小心点。

js中的let

let是块级作用域,函数内部使用let定义后,对函数外部无影响

let c = 3;
console.log('函数外let定义c:' + c);//输出c=3
function change(){
let c = 6;
console.log('函数内let定义c:' + c);//输出c=6
} 
change();
console.log('函数调用后let定义c不受函数内部定义影响:' + c);//输出c=3

区别

X O