作用:用于声明变量,类似于var,但是,它只在let所在的代码块内部有效。
<script type="text/traceur">
{
var a=100;
let b=200;
}
console.log(a); //100
console.log(b); //Error,b is not defined
</script>
性质:
(1)let不存在变量提升(let VS var)
ES5:
<script type="text/traceur">
//ES5
console.log("ES5");
for(var i=0;i<10;i++){
var c=i;
a[i]=function(){
console.log(c);
};
};
a[5](); //9
</script>
ES6:在let声明变量的时候,就不会如此结果,
<script type="text/traceur">
//ES6
console.log("ES6");
for(let j=0;j<10;i++){
let c=j;
a[i]=function(){
console.log(c);
};
};
a[5](); //5
</script>
解析:由于在执行函数时,将j=5作为变量赋值给传入函数中,所以执行完毕即退出。
(2)暂时性死区
即只要块级作用域中存在let命令,所声明的该变量是有效的“绑定的”,不再受外部影响。
案例1:
<script type="text/traceur">
//var a=100;
{
console.log(a); //undefined
let a=100;
console.log(a); //100
}
</script>
解析:a在let a声明前就console了,即表示“未定义undefined”,在let之前的区域为“暂时性死区”。
案例2:
<script type="text/traceur">
var a=100;
{
console.log(a); //undefined
let a=100;
console.log(a); //100
}
</script>
解析:在该案例中,多了“var a”,但是let所声明的变量,并不在乎外界的影响,所以在let作用域内部,var
声明的变量是无效的,即“console.log(a)”还是defined(3)let不允许重复声明情况1:模块内部重复声明(不允
许用let命令重复声明)
案例3:
<script type="text/trancer">
{
var a=1;
var a=2;
}
console.log(a); //2
{
var b=1;
let b=2;
}
console.log(b);
{
let c=1;
let c=2;
}
console.log(c);
</script>
解析:由于var重复声明的变量是可以运行的,即后边的会覆盖前边的变量。但是,只要声明的变量存在let ,则若重复声明一个变量,都会报错。无论有一个let,let在前还是在后;还是有两个重复let声明的变量,都是有错误的。
情况2:模块之间(不影响,可重复声明)
<script type="text/trancer">
{
var a=1;
var a=2;
console.log(a); //2
}
{
let a=2;
console.log(a); //2
}
</script>
(1)ES5 VS ES6
ES5:在ES5中,只有两种作用域:全局作用域 + 局部作用域
场景1——内部作用域会覆盖外部作用域
场景2——用于计数的循环变量泄露为全局变量(循环变量结束,变量依然存在,内存占用)
ES6:增加了“块级作用域”的概念
A.块级作用域
案例1:
<script type=”text/traceur”>
console.log(“ES6:”);
let num=100;
if(true){
let num=200;
}
console.log(num); //100
</script>
<script type=”text/javascript”>
console.log(“ES5”);
var num=100;
if(true){
var num=200;
}
console.log(num); //200
</script>
B.立即执行函数(ES5)
<script type=”text/javascript”>
function fun(){
Console.log(“I am outside!”);
}
(function(){
if(false){
function fun(){
console.log(“I am inside!”);
};
};
fun(); //I am inside!
})();
</script>
ES6:
<script type=”text/traceur”>
function fun(){console.log(“I am outside!”);}
(function(){
if(false){
function fun(){
console.log(“I am inside!”);
};
};
fun(); //I am outside!
})();
3、const命令
(1)Const也是声明变量,但是它声明的是一个常量。一旦声明,就不能改变。
<script type=”text/traceur”>
const Pi =3.1415926;
console.log(Pi);
Pi=3;
console.log(Pi); //Pi is read-only——Error
</script>
1-1:使用const命令
<script type=”text/traceur”>
const Pi=3.1415926;
console.log(Pi);
console.log(5*Pi);
</script>
1-2:const块级作用域
<script type=”text/traceur”>
if(true){
const Pi=3.1415926;
}
console.log(Pi); // Pi is not defined!——error
</script>
1-3:暂时性死区
1-4:不可重复声明
(2)const对象
const命令是指向对象的一个地址
<script type=”text/traceur”>
const person={};
person.name=”Zhangsan”;
person.age=30;
console.log(person.name);
console.log(person.age);
console.log(person) ; //object{name: age}
</script>
<script type=”text/traceur”>
const arr=[];
console.log(arr);
console.log(arr.length);
console.log(“------”);
arr.push(“Hello world!”);
console.log(arr);
console.log(arr.length);
arr.length=0;
console.log(arr.length);
//错误用法
arr = [“Hello world”];
</script>
(4)const对象冻结
<script type=”text/traceur”>
const person = Object.freeze({
name = “Zhangsan”;
age=12;
}); //冻结对象;
console.log(person.name); //Zhangsan
console.log(person.age); //12
console.log(person); //Object
</script>
4-2:彻底对象冻结函数
var constantize=(obj) => {
object.freeze(obj);
object.keys(obj).forEach(key , value) => {
if( typeof obj[key] === ‘object’ ){
constantize( obj[key] );
};
};
};
4、跨模块常量
<script type=”text/traceur”>
// module1.js
export const intVariantName =100;
export const floatVariantName =3.14;
export const charVariantName =”variantValue”;
// user.js
import * as var from ‘./module’;
console.log(variant.IntvariantName); // 100
console.log(variant.floatvariantName); //3.14
console.log(variant.charvariantName); //”variantValue”
//otherUser.js
import{intVariantName,floatVariantName } as variant from ‘./module’;
console.log(variant.IntvariantName); // 100
console.log(variant.floatvariantName); //3.14
</script>
5、全局对象属性
全局对象:最顶层对象。
(1)浏览器环境——window对象;
(2)Node.js——global对象
(3)Javascript——所有全局变量都是全局对象的属性
ES6中规定的,
属于全局对象的属性:var、function声明的全局对象
不属于全局对象属性:let、const、class命令声明的全局对象
案例:全局对象的属性
<script type=”text/traceur”>
var varName =”varValue”;
//浏览器环境
console.log(window.varName); //varValue
//node.js环境
console.log(global.varName); //varValue
//通用环境
console.log(this.varName); //varValue
let letName =”letValue”;
console.log(window.letName); //letValue || undefined—use strict
console.log(this.letName); //letValue || undefined—use strict
</script>
6、变量的解构赋值
Destructuring
(1)数组解构赋值
<script type=”text/traceur”>
// ES5
var a=0;
var b=1;
var c=2;
// ES6
var [a,b,c]=[0,1,2];
console.log(a);
console.log(b);
console.log(c);
</script>
案例1-1:对应位置
let [one, ,three] =[“one”,”two”,”three”];
console.log(one); //one
console.log(three); //three
let [head,...tail] =[0,1,2,3,4,5];
console.log(head); //0
console.log(tail); //[1,2,3,4,5]
案例1-2:不完全解构
定义:等号左边的模式,只匹配一部分的等号右边的数据。(不会出现溢出等现象)
<script type=”text/traceur”>
let [x,y] = [1,2,3];
console.log(x); //1
console.log(y); //2
let [a,[b],c] = [1,[2,3],4];
console.log(a); //1
console.log(b); //2
console.log(c); //4
let [a,[b,d],c] =[1,[2,3],4];
console.log(a); //1
console.log(b); //2
console.log(d); //3
</script>
案例1-3:指定默认值
<script type=”text/traceur”>
var [temp=”string”] = [];
console.log(temp); //string
var [temp=”string” ]= [“tempString”];
console.log(temp); //tempString
var [x=”aaa”,y] = [“bbb”];
console.log(x); //bbb
console.log(y); //undefined
var [m,n=”aaa”] = [“bbb”];
console.log(m); //bbb
console.log(n); //aaa
var [p,q=”aaa”] = [“bbb”,undefined];
console.log(p); //bbb
console.log(q); //aaa(由于undefined是未定义,所以有值即输出)
</script>
注意:非遍历解构产生报错
(2)对象的解构赋值
2-1:对象的属性没有次序,变量必须与属性同名,才可取到正确的值。
<script type=”text/traceur”>
var {name,age}={name:”zhansan”,age:23};
console.log(name);
console.log(age);
</script>
2-2:对象的解构赋值不用按照顺序
2-3:属性名与变量名
由于变量名与属性名并不一致,所以需要如下方式来改变,以实现如上的效果。
案例1:
<script type=”text/traceur”>
var{name:person_name,age:person_age,id:person_id}={id:”007”,age:23,name:”zhangsan”};
console.log(person_name); //zhangsa
console.log(person_age); //23
console.log(person.id); //007
</script>
案例2:
<script type=”text/traceur”>
let object={first:”Hello”,last:”world”};
let {first:firstName,last:lastName} =object;
console.log(firstName); //Hello
console.log(lastName); //world
</script>
2-4:对象解构指定默认值生效条件
默认值生效的条件是,对象的属性值严格等于undefined
<script type=”text/traceur”>
var {a=3} = {a= undefined};
console.log(a); //3
var {b=3} = { b=null };
console.log(b); // null
</script>
2-5:现有对象的方法
<script type=”text/traceur”>
console.log(Math.PI/6);
let {sin,cos,tan} = Math;
console.log(sin(Math.PI/6));
</script>
(3)字符串的解构赋值
字符串被转换为一个类似数组的对象。
属性的解构赋值:由于字符串属性length,可以利用该属性进行解构赋值。
(4)函数参数的解构赋值
案例4-1:函数的解构赋值(略)
案例4-2:函数参数的解构赋值
<script type=”text/traceur”>
function fun( {x=0,y=0} = {} ){
return [x,y];
};
console.log(fun( {x:100,y:200} ) ); //[100,200]
console.log(fun({x:100})); //[100,0]
console.log(fun({})); //[0,0]
</script>
(5)解构赋值的用途
5-1:交换变量的值
案例1:
<script type="text/traceur">
//ES5
console.log("ES5:");
var a=100;
var b=200;
console.log("交换前:");
console.log("a="+a); //100
console.log("b="+b); //200
var temp;
temp=a;
a=b;
b=temp;
console.log("交换后:");
console.log("a="+a); //200
console.log("b="+b); //100
//ES6
console.log("ES6:");
var x,y;
console.log("交换前:");
console.log("a="+a); //100
console.log("b="+b); //200
//利用数组解构的方法进行交换
[x,y] = [y,x];
console.log("交换后:");
console.log("a="+a); //200
console.log("b="+b); //100
</script>
5-2:从函数返回多个值
案例2-1:返回一个数组
<script type="text/traceur">
function fun(){
return [1,2,3];
};
var [x,y,z] = fun();
console.log(x); //1
console.log(y); //2
console.log(z); //3
</script>
案例2-2:返回一个对象
<script type="text/traceur">
function fun(){
return {
id:"007",
name:"zhao",
age:20
};
};
var {id,name,age} = fun();
console.log(id);
console.log(name);
console.log(age);
var {id:person_id,name:person_name,age:person_age} = fun();
console.log(person_id);
console.log(person_name);
console.log(person_age);
</script>
5-3:函数参数的定义
function fun(id,name,age){
};
fun({id:"007",name:"zhao",age:20});
//参数是一组无次序的值
function fun({x,y,z}){
};
fun({x:100,y:200,z:300});
5-4:提取json数据
<script type="text/traceur">
var jsonData ={
id:"007",
name:"zhao",
age:20,
score:[100,90,89]
};
console.log(jsonData);
console.log("ES5");
console.log("Name"+jsonData.name);
console.log("age"+jsonData.age);
console.log("Chinese score"+jsonData.score[0]);
console.log("Math score"+jsonData.score);
console.log("ES6");
let{ id:number, name,age,score.score } =jsonData;
console.log(number);
console.log(name);
console.log(age);
conosle.log(score.Chinese);
</script>
5-5:函数参数的默认值
<script type="text/traceur">
jQuery.ajax =function(url,{
async = true,
beforeSend = function(){},
cache = true,
global = true,
}){
//
};
</script>
5-6:遍历Map结构
<script type="text/traceur">
var map =new Map();
map.set("id","007");
map.set("name","Zhao");
console.log(map); //Map{id => "007",name =>"Zhao"}
console.log(typeOf(map)); //Object
for(let [key,value] of map){
console.log(key+"is" + value);
}
// id is 007
// name is Zhao
//获取键名
for(let[key] of map){
console.log(key);
}
// id
// name
//获取键值
for(let[,value] of map){
console.log(value);
}
// 007
// Zhao
</script>
5-7:输入模块的指定方法
require.js的引用
<script type="text/traceur">
const {SourceMspConsumer,SourceNode } = require("source-map");
</script>