我們在下面的文章中具體講解ES6時,使用Traceur轉碼器的直接插入網頁的方法來轉碼ES6
traceur:是由Google出的編譯器,可以將ES6編譯成ES5
bootstrap:是一個引導程序(與響應式的bootstrap不同)
需要將traceur.js和bootstrap.js下載下來,引入到當前文件中即可
---------------------------------------------------------------------
注意:在使用ES6時,先不用引入任何東西,去測試,
當不支持ES6時,再去引入traceur.js和bootstrap.js對RS6進行轉碼。
以為現在瀏覽器已經支持部分ES6功能,有的不需要轉碼,轉碼反而錯誤
1.let定義變量 ——已經被瀏覽器實現了,不需要編譯
以前定義變量:var a=12;
ES6定義變量:let a=12;
代碼塊:用{}包起來的代碼,稱為代碼塊,如if語句,for循環,while循環
let和var定義變量的區別:
1)let即具有函數作用域,又具有代碼塊作用域
var只有函數作用域
{
let a=12;
alert(a); //正常執行,彈出12
}
alert(a); //報錯,a沒有定義
{
var b=5;
alert(b); //能正常輸出
}
alert(b); //第二次也能夠正常輸出
2)let不允許在相同作用域內,重復聲明同一個變量。
var定義的變量可以重復聲明賦值,且后一次會把前一次的值給覆蓋
// 報錯
function () {
let a = 10;
var a = 1;
}
// 報錯
function () {
let a = 10;
let a = 1;
}
因此,不能在函數內部重新聲明參數。
function func(arg) {
let arg; // 報錯
}
function func(arg) {
{
let arg; // 不報錯
}
}
var b=12;
var b=5; //正常,后一次把前一次的給覆蓋
所以由上面的區別可以看出,let才更接近其他語言的變量
3)var存在變量提升,即變量可以在聲明之前使用,值為undefined
let不存在變量提升,它所聲明的變量一定要在聲明后使用,否則報錯
// var 的情況
console.log(foo); // 輸出undefined
var foo = 2;
// let 的情況
console.log(bar); // 報錯ReferenceError
let bar = 2;
補充:
1.在代碼塊內,使用let命令聲明變量之前,該變量都是不可用的,使用會報錯。
這在語法上,稱為“暫時性死區”(temporal dead zone,簡稱 TDZ)。
if (true) {
// TDZ開始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ結束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
2.只要塊級作用域內存在let命令,它所聲明的變量就“綁定”(binding)這個區域,不再受外部的影響。
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
let的應用:
封閉空間:
之前實現封閉空間的方法:
(function(){
var a=12; //這里的a相當於局部變量
alert(a);
})();
現在使用let就相當於上面的封閉空間了,更加方便,清晰
{
let a=12;
alert(a);
}
例如解決i的問題:
window.onload=function(){
var aBtn=document.getElementsByTagName('input');
for(var i=0;i<aBtn.length;i++){
aBtn.onclick=function(){
alert(i); //這里並不會實現彈出0,1,2
}
}
}
window.onload=function(){
var aBtn=document.getElementsByTagName('input');
for(var i=0;i<aBtn.length;i++){
(function(i){
aBtn.onclick=function(){
alert(i); //使用封閉空間進行解決,彈出0,1,2
}
})(i);
}
}
window.onload=function(){
var aBtn=document.getElementsByTagName('input');
for(let i=0;i<aBtn.length;i++){
aBtn.onclick=function(){
alert(i); //使用let的塊級作用域的特點,代替封閉空間
}
}
}
-----------------------------------------------------------------
for循環中的i問題:
下面的代碼使用var,最后輸出的是10。
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10
上面代碼中,變量i是var聲明的,在全局范圍內都有效。所以每一次循環,新的i值都會覆蓋舊值,導致最后輸出的是最后一輪的i的值。
如果使用let,聲明的變量僅在塊級作用域內有效,最后輸出的是6。
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
上面代碼中,變量i是let聲明的,當前的i只在本輪循環有效,所以每一次循環的i其實都是一個新的變量,所以最后輸出的是6。你可能會問,如果每一輪循環的變量i都是重新聲明的,那它怎么知道上一輪循環的值,從而計算出本輪循環的值?這是因為 JavaScript 引擎內部會記住上一輪循環的值,初始化本輪的變量i時,就在上一輪循環的基礎上進行計算。
另外,for循環還有一個特別之處,就是循環語句部分是一個父作用域,而循環體內部是一個單獨的子作用域。
for (let i = 0; i < 3; i++) {
let i = 'abc';
console.log(i);
}
// abc
// abc
// abc
上面代碼輸出了3次abc,這表明函數內部的變量i和外部的變量i是分離的。
總結:塊級作用域其實就是匿名函數立即調用
--------------------------------------------------------------------------------
2.const定義常量
特點:
1)不能重復聲明(一旦定義就不能修改),且定義時就要給初始值
因為以后再也不能賦值了,所以聲明的時候一定要有值
const a=12;
a=5; //報錯,不能夠修改
const b;
b=5; //報錯,定義時就要給初始值
用途:為了防止意外修改變量,比如引入庫名,組件名等
---------------------------------------------------------------------------------
3.字符串連接
之前都是用+進行字符串連接:
'abc'+變量名+'ef'
var a='我們';
var b='朋友';
var str='大家在一起'+a+'都是好'+b;
定義字符串的另外一種方法,使用反單引號
var str=`` (又稱為字符串模板)
現在結合反單引號定義字符串,使用 ${變量名}進行連接 :
`abc${變量名}ef`
var a='我們';
var b='朋友';
var str=`大家在一起${a}都是好${b}`;
----------------------------------------------------------------------------
4.解構賦值:
var [a,b,c]=[12,2,43];
與json配合使用:與順序無關,前后名稱要相同
var{a,b,c}={a:12,b:5,c:16};
var{a,b,c}={b:5,a:12,c:16};
console.log(a);
模式匹配:左右的模式要相同
var [a,[c,d],b]=[12,[1,5],75];
var [{a,e},[c,d],b]=[{e:'eee',a:'aaa'},[1,5],75];
var arr=[{href:'abc',img:'12',src:'vnf'}];
var [{href,img,src}]=arr;
console.log(href);
之前json做判斷給默認值:
var json={};
var a=json.a||12;
結構賦值給默認值:
var {time=12,id=6}={};
console.log(time,id);
放到返回值里面:
function getPos(){
return {stop:12,left:14};
}
var {stop,left}=getPos;
console.log(stop,left);
------------------------------------------------------------------------
4.復制數組:
方法1:循環
var arr1=[1,2,3];
var arr2=[];
for(var i=0;i<arr1.length;i++){
arr2.push(arr[i]);
}
方法2:Array.from(arr)
var arr1=[1,2,3];
var arr2=Array.from(arr1);
方法3:ES6新增——var arr2=[...arr];
var arr1=[1,2,3];
var arr2=[...arr1]; //復制arr1
[...]也可以與函數的傳參結合在一起
通常我們定義一個函數,參數用arguments來表示,arguments是一個數組,但又不完全具備數組的性質
function show(arguments){
console.log(arguments);
//arguments.push(5); //這個是錯誤的,因為參數是由傳進來的實參決定的
}
show(1,2,3,4);
我們可以通過...來方便的將arguments轉變成一個真正的數組
function show(...args){
console.log(args);
args.push(5);
console.log(args); //1,2,3,4,5
}
show(1,2,3,4);