1. 程式人生 > >ES6函數比對ES5函數

ES6函數比對ES5函數

cto 箭頭函數 pan ply 單獨 {} pos efi 直接

簡介

這裏只做簡單的ES6函數與ES5函數對比,把ES6函數中新增的方法或者用法介紹一下。方便大家學習、記憶。隨著社會發展,瀏覽器肯定會在不久全部支持ES6語法,因為現在的IE8用戶都很少了,做web前端將不再受此束縛!

函數參數的默認值

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

//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 參數搭配的變量是一個數組,該變量將多余的參數放入數組中。例:

//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的同學我們也要抓緊學習啦!

ES6函數比對ES5函數