一、具備的基礎知識 1.扎實的HTML/CSS/Javascript基本功,這是前置條件。 2.不要用任何的構建項目工具,只用最簡單的<script>,把教程里的例子模仿一遍,理解用法。不推薦上來就直接用 vue-cli 構建項目,尤其是如果沒有 Node/Webpack 基礎。 另外在這裡大家補充 ...
一、具備的基礎知識
1.扎實的HTML/CSS/Javascript基本功,這是前置條件。
2.不要用任何的構建項目工具,只用最簡單的<script>,把教程里的例子模仿一遍,理解用法。不推薦上來就直接用 vue-cli 構建項目,尤其是如果沒有 Node/Webpack 基礎。
另外在這裡大家補充點ES6的語法。
二、什麼是ECMAScript,以及es6的誕生?
1997年 ECMAScript 1.0 誕生
1999年12月 ECMAScript 3.0誕生,它 是一個巨大的成功,在業界得到了廣泛的支持,它奠定了JS的基本語法,被其後版本完全繼承。直到今天,我們一開始學習JS,其實就是在學3.0版的語法
2000年的ECMAScript4.0是當下ES6的前身,但由於這個版本太過激烈,對ES3做了徹底升級,所以暫時被“和諧”了
2009年12月,ECMAScript5.0版正式發佈。ECMA專家組預計ECMAScript的第五個版本會在2013年中期到2018年作為主流的開發標準。2011年6月,ES5.1版發佈,並且成為ISO國際標準
2013年,ES6草案凍結,不再添加新的功能,新的功能將被放到ES7中;2015年6月,ES6正式通過,成為國際標準
好的,介紹es6的誕生,我們簡單來學幾個es6的語法,僅僅的只是為了後面咱們vue的課程做課前準備。如果感興趣的同學可以查看
es6語法:let和const
es6新增了let命令,用來聲明變數。它的用法類似於var,但是所聲明的變數,只在let命令所在的代碼塊內有效。
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1
上面代碼在代碼塊之中,分別用let
和var
聲明瞭兩個變數。然後在代碼塊之外調用這兩個變數,結果let
聲明的變數報錯,var
聲明的變數返回了正確的值。這表明,let
聲明的變數只在它所在的代碼塊有效。
for
迴圈的計數器,就很合適使用let
命令。
for (let i = 0; i < 10; i++) { // ... } console.log(i); // ReferenceError: i is not defined
上面代碼中,計數器i
只在for
迴圈體內有效,在迴圈體外引用就會報錯。
下麵的代碼如果使用var
,最後輸出的是10
。
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10
上面代碼中,變數i
是var
命令聲明的,在全局範圍內都有效,所以全局只有一個變數i
。每一次迴圈,變數i
的值都會發生改變,而迴圈內被賦給數組a
的函數內部的console.log(i)
,裡面的i
指向的就是全局的i
。也就是說,所有數組a
的成員裡面的i
,指向的都是同一個i
,導致運行時輸出的是最後一輪的i
的值,也就是 10。
如果使用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); }
不存在變數提升
var
命令會發生”變數提升“現象,即變數可以在聲明之前使用,值為undefined
。這種現象多多少少是有些奇怪的,按照一般的邏輯,變數應該在聲明語句之後才可以使用。
為了糾正這種現象,let
命令改變了語法行為,它所聲明的變數一定要在聲明後使用,否則報錯。
// var 的情況 console.log(foo); // 輸出undefined var foo = 2; // let 的情況 console.log(bar); // 報錯ReferenceError let bar = 2;
上面代碼中,變數foo
用var
命令聲明,會發生變數提升,即腳本開始運行時,變數foo
已經存在了,但是沒有值,所以會輸出undefined
。變數bar
用let
命令聲明,不會發生變數提升。這表示在聲明它之前,變數bar
是不存在的,這時如果用到它,就會拋出一個錯誤。
暫時性死區
只要塊級作用域記憶體在let
命令,它所聲明的變數就“綁定”(binding)這個區域,不再受外部的影響。
不允許重覆聲明
let
不允許在相同作用域內,重覆聲明同一個變數
// 報錯 function func() { let a = 10; var a = 1; } // 報錯 function func() { let a = 10; let a = 1; }
因此,不能在函數內部重新聲明參數。
function func(arg) { let arg; // 報錯 } function func(arg) { { let arg; // 不報錯 } }
為什麼需要塊級作用域?
ES5 只有全局作用域和函數作用域,沒有塊級作用域,這帶來很多不合理的場景。
第一種場景,內層變數可能會覆蓋外層變數。
var tmp = new Date(); function f() { console.log(tmp); if (false) { var tmp = 'hello world'; } } f(); // undefined
上面代碼的原意是,if
代碼塊的外部使用外層的tmp
變數,內部使用內層的tmp
變數。但是,函數f
執行後,輸出結果為undefined
,原因在於變數提升,導致內層的tmp
變數覆蓋了外層的tmp
變數。
第二種場景,用來計數的迴圈變數泄露為全局變數。
var s = 'hello'; for (var i = 0; i < s.length; i++) { console.log(s[i]); } console.log(i); // 5
上面代碼中,變數i
只用來控制迴圈,但是迴圈結束後,它並沒有消失,泄露成了全局變數。
const命令
基本語法
const
聲明一個只讀的常量。一旦聲明,常量的值就不能改變。
const PI = 3.1415; PI // 3.1415 PI = 3; // TypeError: Assignment to constant variable.
const
聲明的變數不得改變值,這意味著,const
一旦聲明變數,就必須立即初始化,不能留到以後賦值。
const foo; // SyntaxError: Missing initializer in const declaration
const
的作用域與let
命令相同:只在聲明所在的塊級作用域內有效。
if (true) { const MAX = 5; } MAX // Uncaught ReferenceError: MAX is not defined const命令聲明的常量也是不提升,同樣存在暫時性死區,只能在聲明的位