ES6函數比對ES5函數

簡介

這裏只作簡單的ES6函數與ES5函數對比,把ES6函數中新增的方法或者用法介紹一下。方便你們學習、記憶。隨着社會發展,瀏覽器確定會在不久所有支持ES6語法,由於如今的IE8用戶都不多了,作web前端將再也不受此束縛!前端

函數參數的默認值

其餘語言已經支持函數參數默認值,我們Js也不會落後的。例:es6

//es6寫法
/**
 * @a {number} 默認值10
 * @b {number} 默認值20
 * */
function fn(a=10,b=20){
	console.log(a,b);
}
fn();//沒有傳遞參數
fn(1,3);//傳遞了參數

//es5寫法
/**
 * @a {number} 默認值10
 * @b {number} 默認值20
 * */
function fn(a, b) {
  a = a || 10;//設置默認值
  b = b || 20;//設置默認值
  console.log(a, b);
}	
複製代碼
  1. 先說說es5寫法這種寫法,若是a傳遞的是false或者(求值爲false的值) 則a會使用默認值10,這樣代碼就沒有按照咱們指望的那樣去執行。
//修改es5寫法讓它實現相似於es6:
//es5寫法
/**
 * @a {number} 默認值10
 * @b {number} 默認值20
 * */
function fn(a, b) {
   a = a!==undefined?a:10;//設置默認值
   b = b!==undefined?b:20;//設置默認值
  console.log(a, b);
}	
複製代碼
  1. es6寫法若是傳入undefined,將觸發該參數等於默認值,其餘值不會觸發默認值。
  2. es6設置默認參數值,在函數體內不容許再次使用let或者const聲明。例:
/**
 * es6寫法
 * @a {number} 默認值10
 * @b {number} 默認值20
 * */
function fn(a=10,b=20){
    let a=100;//會報錯哦!
    const b=20;//會報錯哦!
	console.log(a,b);
}
複製代碼
  1. 設置參數默認值會產生單獨的做用域。
/**
 * es6寫法
 * 默認值會產生單獨的做用域,做用域的代碼也是按照先左後右順序執行。
 * @a {number} 默認值10
 * @b {number} 默認值10+20
 * */
function fn(a=10,b=a+20){//若是這裏是(a=b+20,b=10)調用時a沒有傳遞參數此時會報錯!
	console.log(a,b);
}
//複雜的例子
/*-----------一條華麗的分割線-------------*/

/**
 * ----------默認值會產生單獨的做用域-----------
 * 調用函數fn 時,未傳遞參數,【默認參數單獨做用域】a值爲undefined,b值爲undefined。
 * 當執行b()函數時,則查找到a值爲undefined,不在查找全局a。
 * 所以爲結果爲:a的值爲: undefined
 * */
var a='全局變量';
function fn(a,b=function(){ console.log('a的值爲:',a);}){
	b();
}
fn();//a的值爲: undefined

/**
 * ----------默認值會產生單獨的做用域-----------
 * 調用函數fn 時,未傳遞參數,b值爲undefined。
 * 當執行b()函數時,則尋找a值發現全局a。
 * 所以爲結果爲:a的值爲: 全局變量
 * */
var a='全局變量';
function fn(b=function(){ console.log('a的值爲:',a);}){
	b();
}
fn();//a的值爲: 全局變量

**
 * 如今再來理解一下這個。看看你能答對嗎?
 * */
var a = '小小坤';
function fn(a, y = function() {a = '小小坤1';}) {
   var a = '小小坤2';
   y();
  console.log(a);
}

fn() // 答案是?
console.log(a); // 答案是?
複製代碼
  1. 使用參數默認值時,函數不能有同名參數。
function fn(a,a,b){
	console.log(a,b);//不報錯
}
function fn(a,a,b=1){
	console.log(a,b);//報錯
}
複製代碼

rest 參數

ES6 引入 rest 參數(形式爲...變量名),用於獲取函數的多餘參數,這樣就不須要使用arguments對象了。rest 參數搭配的變量是一個數組,該變量將多餘的參數放入數組中。例:web

//es6寫法
/**
 * @b {arry} 參數列表
 *  
 * */
function fn(...b){
	b.push('小小坤');
	console.log(b);
}
fn(1,'20');//[1, "20", "小小坤"]

//es5寫法
/**
 * @a {number} 參數a
 * @b {number} 參數b
 * */
function fn(a, b) {
   var arg=[].slice.call(arguments);
   arg.push('小小坤');
   console.log(arg);
}
複製代碼

須要注意的是:數組

  1. 函數length 屬性不包含rest 參數
(function(a) {}).length  // 1
(function(...a) {}).length  // 0
(function(a, ...b) {}).length  // 1
複製代碼
  1. rest 參數不能夠這樣使用,只能是最後一個參數
function fn (a,...b,d){
   //會報錯!	
}
複製代碼

箭頭函數

使用時注意事項:

1)函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。
2)不能夠看成構造函數,也就是說,不可使用new命令,不然會拋出一個錯誤。
3)不可使用arguments對象,該對象在函數體內不存在。若是要用,能夠用 rest 參數代替。
4)不可使用yield命令,所以箭頭函數不能用做 Generator 函數。
複製代碼
簡單例子
/*-----------例子--1------*/
//es6寫法
var fn = n => n;

//等同於es5 寫法
var fn = function(n) {
  return n;
};
複製代碼
/*-----------例子--2------*/
//es6寫法
var fn = () => 5;
// 等同於 es5 寫法
var fn = function () { return 5 };
複製代碼
/*-----------例子--3------*/
//es6寫法
var sum = (n1, n2) => n1 + n2;
// 等同於es5 寫法
var sum = function(n1, n2) {
  return n1 + n2;
};
複製代碼

若是箭頭函數的代碼塊部分多於一條語句,就要使用大括號將它們括起來,而且使用return語句返回。瀏覽器

/*-----------例子--4------*/
//es6寫法
var sum = (n1, n2) => { return n1+n2; }

//因爲大括號被解釋爲代碼塊,因此若是箭頭函數直接返回一個對象,必須在對象外面加上括號,不然會報錯。
// 報錯
let fn = id => { id: id, age: 18 };

// 不報錯
let fn = id => ({ id: id, age: 18  });
複製代碼
/*-----------例子--5------*/

function fn() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

fn.call({ id: 42 });
// id: 42


//ES5代碼須要這樣寫
function fn() {
  var _this=this;//存儲this
  setTimeout(function() {
    console.log('id:', _this.id);
  }, 100);
}
var id = 21;
fn.call({ id: 42 });
/**
 *  上面代碼中,setTimeout的參數是一個箭頭函數,這個箭頭函數的定義生效是在fn函數生成時,
 *  而它的真正執行要等到 100 毫秒後。若是是普通函數,執行時this應該指向全局對象window,
 *  這時應該輸出21。可是,箭頭函數致使this老是指向函數定義生效時所在的對象(本例是{id: 42}),
 *  因此輸出的是42。
 *  箭頭函數可讓setTimeout裏面的this,綁定定義時所在的做用域,而不是指向運行時所在的做用域。
 * 
 *  另外,因爲箭頭函數沒有本身的this,因此固然也就不能用call()、apply()、bind()這些方法去改變this的指向。
 * */
複製代碼
  1. this指向
//this指向lib
var lib={
	option:{
		name:'小小坤'
	},
	init(){
		this.click();
	},
	click(){
		setTimeout(()=>{
			console.log(this.option.name);
		},2000);
	}
}
lib.init();//小小坤
複製代碼
  1. 不能使用構造函數
var des=(n)=>{this.n=n};
new des(1);//des is not a constructor
//由於沒有this
複製代碼
  1. 沒有arguments屬性
var des=(n)=>{console.log(arguments)};
des();//arguments is not defined
//能夠這樣使用
var des=(...n)=>{console.log(n)};
des(1,2,3,4,5);//[1,2,3,4,5]
複製代碼

總結

通過以上對比能夠看出ES6寫的代碼會愈來愈少,代碼質量也逐漸提高。好比默認參數,箭頭函數,還有rest 參數,使用起來爽爆棚!沒有在開發環境使用的ES6的同窗咱們也要抓緊學習啦!bash

相關文章
相關標籤/搜索