变量:存储信息的容器,在ES中变量是松散类型。
松散类型:不对数据类型做限制,前端js的基本数据类型都可以保存。
关于ES5和ES6在声明变量上的区别以及特性:
ES5:ES5中声明变量只提供了var和function两种形式
// var特性:
// 1.声明变量可以不用指定初始值,会保存一个特殊的值undefined (但会在栈内存中开辟一个内存空间)
var a;
console.log(a); //undefined
// 2.变量可以重复定义,且可以修改值
var a = 3;
console.log(a); //3
// 3.函数内重复定义变量对函数外无影响(局部变量)
function test(){
var a = 4;
console.log(a); //4
}
test();
console.log(a); //3
// 4.函数内重新赋值对函数外有影响
function test1(){
a = 5;
console.log(a); //5
}
test1();
console.log(a); //5
// 5.变量声明语句自动提升到所在作用域的顶端
// 原程序代码:
test1();
var a = 5;
function test1(){
console.log("len");
}
// 程序执行后:
var a; //变量声明提升到顶部
function test1(){ //声明函数整体提升到顶部
console.log("len");
}
test1();
a =5; //变量初始化赋值位置不变
// function特性
// 1.function声明的函数也存在整体声明提升
// 2.函数声明优于变量声明
console.log(typeof a); // function
var a = 1;
function a(){}
console.log(typeof a); // number
// 3.同名函数声明以最后的为准(因为函数声明赋值和var不同,赋值在执行上下文的时候就进行了)
var a = 1;
console.log(a); // 1
test();
console.log(a); // 6
function test(){
a = 4;
}
function test(){
a = 6;
}
总结:var和function都拥有声明提升,从整体声明提升来看,function优于var,但是是因为function在执行上下文的开始阶段进行的,而var不论是赋值undefined还是初始值,都在执行语句的位置进行赋值。
ES6:ES6中新增了let、const、import、Class 四种形式
// let特性
// 1.let声明的变量只在他所在的代码块中有效
// 2.不存在变量提升
{
console.log(a); // a is not defined
let a = 1;
console.log(a); // 1
}
// 3.不可以重复定义(仅限所在代码块作用于不可重复定义,也叫暂时性死区)
// 编译不通过:Duplicate declaration "a"
let a = 1;
let a = 2;
//正确的使用
let a = 1;
test();
test1();
function test(){
let a = 4;
console.log(a); // 4
}
function test1(){
let a = 5;
console.log(a); // 5
}
console.log(a); // 1
//const特性
// 1.const在声明之初就要赋值,不能留到后面 (编译不通过)
const API;
console.log(API) // SyntaxError: Missing initializer in const declaration
// 2.不存在变量提升
console.log(API); // Uncaught ReferenceError: MAX is not defined
const API = 1;
// 3.不允许重复声明(编译不通过,也叫暂时性死区)
const MAX = 1;
const MAX = 2;
console.log(MAX); // Identifier 'MAX' has already been declared
// 4.一旦声明,就不能再次改变(编译不通过)
const MAX = 1;
MAX =3
console.log(MAX); // Identifier 'MAX' has already been declared
// 5.声明的变量只在块级作用域内有效
const MAX1 = 1;
console.log(MAX1); // 1
f1()
function f1() {
console.log(MAX1); // 1
}
f2()
function f2() {
const MAX2 = 1;
console.log(MAX2); // 1
}
console.log(MAX2); // MAX2 is not defined
// import特性 (代替使用require进行模块导入,使用export输出,import输入)
// 1.声明提升,提升到整个模块的顶部
// 2.import命令接收的的对象变量名称要与export的对外名称相同
import {$} from './jquery.js'
// 3.可以通过as关键字指定别名
import { New as $ } from './jquery.js';
// class特性
// 1.通过new来生成实例对象
class AB {}
let b = new AB();
// 2.所有的类都有构造函数(constructor),不写默认自带一个无参构造函数
// 3.实质上是一个函数对象,类中的方法和对象都挂在对应函数对象的prototype属性下
class B {}
let b = new B();
b.constructor === B.prototype.constructor // true
// 4.支持表达式形式定义
let a = class A {
getClassName() {
return "hello";
}
};
// 5.不存在变量提升,因此声明定义必须在使用之前
总结:
1.暂时性死区:在一个块级作用域中,变量唯一存在,一旦在块级作用域中用let声明了一个变量,那么这个变量就唯一属于这个块级作用域,不受外部变量的影响