ES6新特性:Function函數擴展, 擴展到看不懂


  本文所有Demo的運行環境為nodeJS, 參考:讓nodeJS支持ES6的詞法----babel的安裝和使用 

   函數的默認值:

  如果有參數 ,那就用參數, 如果沒有參數, 那就用默認的參數;

  ajax的請求經常要做這些判斷, ES6規定了新的表達式, 讓判斷參數的邏輯更加簡單;

function fn(a = 1, b = 2, c = 3) {
    console.log(a,b,c);
}
fn(); //輸出 1, 2, 3;
fn(4,5,6); //輸出 4, 5, 6

  如果調用函數的時候不想給函數傳參, 用函數的默認值, 那么要傳一個undefined;

function fn(a = 1, b = 2, c = 3) {
    console.log(a,b,c);
}
fn(undefined, 1 ,2); //輸出 1, 1, 2
// 以下這種寫法, 會要報異常的;
fn( , 1 ,2);

  要注意的一種情況, 如果要給函數傳了默認值, 函數的length為: 該函數預期傳入的參數的長度, 不包含已經定義默認值的參數;

function fn(a = 1, b = 2, c = 3) {

};
console.log(fn.length); //輸出: 0

  函數默認值也可以是一個函數;

function fn(x,y,f = (x,y) => x*y ) {
    return f(x,y);
};
console.log( fn(4,5) ); //輸出:20
console.log( fn(4,5, (x,y) => x+y) ); //輸出:9

  函數默認值得一個實際應用, 設置一個參數為必須傳, 不傳者報錯;

function fn( foo = (()=>{throw new Error("Missing parameter")})()) {
    console.log(foo)
 }
fn(1);
fn(); //如果沒有傳參數 , 那么會拋 異常;

  rest參數和擴展運算符

  rest參數和擴展運算符這兩個表達式是相反的操作, 用處比較廣, 方便了不少

  function (...args) {}這里面的...args就叫做rest參數;

  ...[1,2,3,4]這種方式叫做擴展運算符;

  下面這個Demo可以看出來 arr [...arr]是相等的,  這個等式適用於一般的數組:

let arr = [1,2,3,4];
console.log( arr.toString() ===[...arr].toString() ); //輸出  : true

  rest參數, 一般都是作為定義函數時候的參數, 一般是function( (...args) ){}或者function (foo, bar, ...args) {} 這樣用的:

let fn = (...args) => {
    return args;
};
console.log(fn(1,2,3,4));  // 輸出 : [ 1, 2, 3, 4 ]

  獲取元素的最小值的demo, 雖然沒有什么卵用

let min = (...args) => {
        return  Math.min.apply(null, typeof args[0] === "object" ? args[0] : args);
};
console.log(min([2,1,5,7,-2])); //輸出 -2;
console.log(min(2,1,5,7,-2)); //輸出 -2;

 

  ...rest 這種獲取參數的方式不能用默認值, 否則要拋異常;

let min = (...args = [2,1]) => { 
    return Math.min.apply(null, args);
};
console.log(min());

  擴展運算符的使用:

let args = [1,2,3,4];
console.log(...args);

  擴展運算符能用作函數的調用, 沒發現其他的好處:

let fn = function (...args) {
    let insideFn = () => {
        console.log(arguments);
    };
    insideFn(...args);
};
console.log( fn(1,2,3,4) );

  實際應用,我們想給一個數組的頭部加一個數據,尾部再加一個數據;

let fn = function(...args ) {
    console.log(args)
};
let arr = [1,2,3,4];
fn(0,...arr,5); //輸出 [ 0, 1, 2, 3, 4, 5 ]

  或者用來合並數組:

console.log([...[1,2],...[3,4],...[5,6]]); //輸出[ 1, 2, 3, 4, 5, 6 ]

let [arr0, arr1, arr2] = [[0],[1],[2]];
console.log([...arr0,...arr1, ...arr2] ); //輸出 : [ 0, 1, 2 ]

 

  擴展運算符內部調用的是Inerator接口, 只要是具有Iterator接口的對象,都可以用擴展運算符,比如Map和Generator:

let map = new Map([
    [1,"one"],
    [2,"two"],
    [3,"three"]
]);
console.log(...map.keys()); // 1 2 3
console.log(...map.values()); //one two three
let fn = function* () {
    yield 1;
    yield 2;
    yield 3;
    yield 4;
};
console.log( ...fn() ); //輸出 1 2 3 4;

  ES6的箭頭函數:

  ES5和ES3定義函數基本都這樣:

function Fn() {
    
}    

  ES6以后就厲害了, 我們還能用箭頭函數表達一個函數, 如下表示的是返回參數的平方:

let fn = (x) => x*x;
console.log(fn(10));

  在使用箭頭函數的時候, 要直接返回 一個對象的話,return的對象要用括號()括起來, 因為大括號是底層開始解釋js代碼標志, 所以用括號括起來;

let fn = () => ({a:10,b:20});
console.log(fn())

  箭頭函數的this指向一定要注意:

let fn = () => {
    return this;
};
console.log(fn); //此時的this為fn;

let fn1 = () => console.log(this); //如果是在瀏覽器環境運行的話, 那么此時this為window,如果在node環境下運行this為undefined;
fn1();

  箭頭函數里面的this不是調用箭頭函數的this, 箭頭函數雖然也有自己的作用域鏈, 但是箭頭函數沒有this, 箭頭函數的this為:離箭頭函數最近的一個通過function(){}創建的函數的this, 說不清的話, 看下Demo....

(function fn(){
    let Fn =  ()  => {
        this.x = 0;
        this.y = 1;
        return this;
    };
    //Fn = Fn.bind(new Object);
    console.log( Fn.call(new Object) ); //輸出結果: { obj: 1, x: 0, y: 1 }
}.bind({obj:1}))();

  以上Demo能夠說明, 箭頭函數的作用域內的this和誰調用它沒有關系

  當然, 箭頭函數的this跟方法也沒有關系;

(function() {
    let obj = {
        method : () => {
            console.log(this);
        }
    };
    obj.method();
}.bind("hehe"))()

    也正因為箭頭函數的this和箭頭函數一點關系都沒有, 所以箭頭函數不能作為構造函數

    箭頭函數的內部無法獲取到arguments;

    箭頭函數不能作為Generator;

  ES7提供了一個很方便去綁定作用域的寫法

  ES3和ES5和ES6, 綁定作用域都用bind, 或者call, 或者apply, 好家伙, 現在用 :: 兩個冒號

foo::bar;
// 等同於
bar.bind(foo);

const hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn(obj, key) {
    return obj::hasOwnProperty(key);
};
*/


let query = document.querySelectorAll.bind(document)
等同於:
let query = document::document.querySelectorAll;

   

  參考: 

    Arrow functions : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

    ruanyifeng:http://es6.ruanyifeng.com/#docs/function

 

作者: NONO
出處:http://www.cnblogs.com/diligenceday/
QQ:287101329
微信:18101055830 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM