學習 Vue.js 需要掌握的 es6 (1)
針對之學習 Vue
用到的 es6
特性,做下簡單總結。
var、let 與 const
var 與 let
es6
之前,JavaScript 並沒有塊級作用域,所謂的塊,就是大括號裏面的語句所組成的代碼塊,比如
function fire(bool) { if (bool) { var foo = "bar"; } console.log(foo); } fire(true); //=> bar
雖然變量 foo
位於 if
語句的代碼塊中,但是 JavaScript 並沒有塊級作用域的概念,因此被添加到了當前的執行環境 - 即函數中,在函數內都可以訪問到。
另外一個令人困惑的地方是變量提升:
function fire(bool) { if (bool) { var foo = "bar"; } else { console.log(foo); } } fire(false); //=> undefined
我們都知道,直接訪問一個未定義的變量,會報錯:
console.log(nope); //=> Uncaught ReferenceError: nope is not defined
但是在上述的例子中,會返回 undefined
。也就是說,變量的定義被提升到了作用域的頂部,等價於:
function fire(bool) { var foo; if (bool) { foo = "bar"; } else { console.log(foo); } } fire(false);
而在 JavaScript 中,聲明但是未賦值的變量會被賦值為 undefined
,因此,結果輸出 undefined
。
為了解決上述問題,引入了 let
關鍵字,let
定義的變量。
首先,let
定義的變量只在代碼塊內有效:
function fire(bool) { if (bool) { let foo= "bar"; } console.log(foo); } fire(true); //=> Uncaught ReferenceError: foo is not defined
其次, let
定義的變量不存在變量提升:
function fire(bool) { if (bool) { let foo = "bar"; } else { console.log(foo); } } fire(false); //=> Uncaught ReferenceError: foo is not defined
因此,使用 let
,上述問題完全解決,這也告訴了我們,應當盡可能的避免用 var
,用 let
來代替,除非你需要用到變量提升。
const
const
與 let
的基本用法相同,定義的變量都具有塊級作用域,也不會發生變量提升。不同的地方在於,const
定義的變量,只能賦值一次。
對於基本類型來說,需要通過賦值來改變其值,因此 const
定義之後就相當於無法改變:
const a = 1; a = 2; // Uncaught TypeError: Assignment to constant variable. ++a; // Uncaught TypeError: Assignment to constant variable.
對於數組和對象來說,值是可以改變的:
const arr = ["a","b","c"]; arr.push("d"); arr.pop();
那麽什麽時候使用 const
呢? 在一些不需要重復賦值的場合可以用:
const provinces = [];
const months = [];
總而言之,多用 let
和 const
,少用 var
。
箭頭函數
在 Vue 中,使用箭頭函數的最大好處就是可以讓 this
指向 Vue 實例:
var vm = new Vue({ el:‘#root‘, data:{ tasks:[] }, mounted(){ axios.get(‘/tasks‘) .then(function (response) { vm.tasks = response.data; }) } });
由於回調函數的 this
指向全局對象 window
,因此,我們需要通過 vm
來訪問實例的方法,如果使用箭頭函數,則可以寫成:
new Vue({ el:‘#root‘, data:{ tasks:[] }, mounted(){ axios.get(‘/tasks‘) .then(response => this.tasks = response.data); } });
箭頭函數的 this
對象始終指向定義函數時所在的對象,相當於:
var vm = new Vue({ el:‘#root‘, data:{ tasks:[] }, mounted(){ var that = this; axios.get(‘/tasks‘) .then(function (response) { that.tasks = response.data; }) } });
模板字符串
模板字符串為 Vue 的組件模板定義帶來了巨大的便利,在此之前,需要這樣定義一個模板:
let template = ‘<div class="container"><p>Foo</p></div>‘;
如果要寫成多行,可以用反斜杠:
let template = ‘<div class="container"> <p>Foo</p> </div>‘;
或者使用數組形式:
let template = [ ‘<div class="container">‘, ‘<p>Foo</p>‘, ‘</div>‘ ].join(‘‘);
如果要嵌入變量,可以寫成:
let name = "jack";
let template = `<div class="container"><p>` + name + ‘</p></div>‘;
而使用模板字符串,則可以方便的在多行裏面編寫模板:
let template = `
<div class="container">
<p>Foo</p>
</div>
`
由於模板字符串的空格和換行會被保留,為了不讓首行多出換行符,可以寫成:
let template = `<div class="container"> <p>Foo</p> </div> `
或者使用 trim()
方法從字符串中移除 前導 空格、尾隨空格和行終止符。
let template = `
<div class="container">
<p>Foo</p>
</div>
`.trim();
模板字符串嵌入變量或者表達式的方式也很簡單:
let name = "jack"; let template = ` <div class="container"> <p>${name} is {100 + 100}</p> </div> `.trim();
默認參數
在 es6
之前,JavaScript 不能像 PHP 那樣支持默認參數,因此需要自己手動定義:
function takeDiscount(price, discount){ discount = discount || 0.9; return price * discount; } takeDiscount(100);
es6
則允許定義默認參數
function takeDiscount(price, discount = 0.9){ return price * discount; } takeDiscount(100);
甚至可以以函數形式傳遞參數:
function getDiscount(){ return 0.9; } function takeDiscount(price, discount = getDiscount()){ return price * discount; } takeDiscount(100);
rest 參數
先從函數的參數傳遞說起:
function sum(a,b,c){ let total = a + b + c; return total; } sum(1, 2, 3);
在 JavaScript 中,函數參數實際上以數組的方式進行傳遞,參數會被保存在 arguments
數組中,因此上例等價於:
function sum(){ let total = arguments[0] + arguments[1] + arguments[2]; return total; } sum(1, 2, 3);
不過 arguments
不單單包括參數,也包括了其他東西,因此沒法直接用數組函數來操作 arguments
。如果要擴展成任意多個數值相加,可以使用循環:
function sum() { let total = 0; for (let i = 0; i < arguments.length; i++) { total = total + arguments[i]; } return total; } sum(1, 2, 3, 4, 6);
es6
則提供了 rest 參數來訪問多余變量,上例等價於:
function sum(...num) { let total = 0; for (let i = 0; i < num.length; i++) { total = total + num[i]; } return total; } sum(1, 2, 3, 4, 6);
可以以變量形式進行傳遞:
function sum(...num) { let total = 0; for (let i = 0; i < num.length; i++) { total = total + num[i]; } return total; } let nums = [1, 2, 3, 4, 6]; sum(...nums);
在函數中體內,num
就是單純由參數構成的數組,因此可以用數組函數 reduce
來實現同樣的功能:
function sum(...num) { return num.reduce( (preval, curval) => { return preval + curval; }) } sum(1, 2, 3, 4, 6);
...
還可以與其他參數結合使用,只需要將其他參數放在前面即可:
function sum(total = 0, ...num) { return total + num.reduce( (preval, curval) => { return preval + curval; }); } let nums = [1,2,3,4]; sum(100, ...nums);
對象的簡寫
函數的簡寫
函數的簡寫,在 Vue
中會用到:
Vue({ el: ‘#root‘, data:data, methods: { addName: function() { vm.names.push(vm.newName); vm.newName = ""; } } });
可以簡寫為:
new Vue({ el: ‘#root‘, data:data, methods: { addName() { vm.names.push(vm.newName); vm.newName = ""; } } });
在組件中頻繁用到:
Vue.component(‘example‘,{ data(){ return { }; } });
屬性的簡寫
let data = { message: "你好,Vue" }; var vm = new Vue({ el: ‘#root‘, data:data })
可以簡寫成:
let data = { message: "你好,Vue" }; var vm = new Vue({ el: ‘#root‘, data })
也就是說,可以直接在對象中直接寫入變量,當函數的返回值為對象時候,使用簡寫方式更加簡潔直觀:
function getPerson(){ let name = ‘Jack‘; let age = 10; return {name, age}; // 等價於 // return { // name : name, // age : age // } } getPerson();
解構賦值
解構賦值可以方便的取到對象的可遍歷屬性:
let person = { firstname : "steve", lastname : "curry", age : 29, sex : "man" }; let {firstname, lastname} = person; console.log(firstname, lastname); // 等價於 // let firstname = person.firstname; // let lastname = person.lastname;
可以將其用於函數傳參中:
function greet({firstname, lastname}) { console.log(`hello,${firstname}.${lastname}!`); }; greet({ firstname: ‘steve‘, lastname: ‘curry‘ });
學習 Vue.js 需要掌握的 es6 (1)