ES6中的函數(函數參數、默認值、箭頭函數)


一、函數參數的解構賦值

function foo([a,b]) {
      console.log(a+b); // 3
}
foo([1,2]);

function bar({c,d}) {
      console.log(c+d); // 7
}
bar({c:3,d:4});

二、函數默認參數

2.1 基本方式

function foo(a,b=10) {
      console.log(a+b); // 1+10=11 => 11
}
foo(1);

function bar([a,b=10]) {
      console.log(a+b); // 3+10=13 => 13
}
bar([3]);

function fn({a,b=10}) {
      console.log(a+b); // 5+10=15 => 15
}
fn({a:5});

2.2 可以預設實參

function bar([a,b=10] = [20]) {
      console.log(a+b); // 20+10=20 => 20
}
bar();

function fn({a,b=10} = {a:20}) {
      console.log(a+b); // 20+10=30 => 30
}
fn();

2.3 預設實參的覆蓋

但如果傳入實參,那么就會把預設的覆蓋。

function bar([a,b=10] = [20]) {
      console.log(a+b); 
}
bar([100]); // 100+10 => 110
bar([100, 200]); // 100+200 => 300

function fn({a,b=10} = {a:20}) {
      console.log(a+b); 
}
fn({a:100}); // 100+10 => 110
fn({a:100,b:200}); // 100+200 => 300

2.4 默認值可以是函數

function getB() {return 10};
function foo(a,b=getB()) {
      console.log(a+b); // 1+10=11 => 11
}
foo(1);

三、箭頭函數

語法:參數=>函數體

  • 單行語句可以省略花括號,如果還是return語句,還可以省略return關鍵字。
  • 多行語句不可以省略花括號。
  • 一個參數可以省略圓括號,多個參數不可以省略圓括號。
// 傳統寫法(無參數)
let fn = function() {return 1;}
// 箭頭函數寫法
let fn = ()=>(1);
let fn = ()=>1;

// 傳統寫法(一個參數)
let bar = function(a) {return 2};
// 箭頭函數寫法
let bar = (a)=>2;
let bar = a=>2;

// 傳統寫法(多個參數)
let fn = function(a,b) {return a+b};
// 箭頭函數寫法
let fn = (a,b)=>a+b;

// 多行語句時不可省略花括號
let br = function(a,b) {
      let res = a+b;
      return res;
}
let br = (a,b)=>{
      let res = a+b;
      return res;
}

四、箭頭函數的特點

4.1 箭頭函數內的this固定化

函數體內的this對象是固定的,就是定義時所在的對象,而不是使用時所在的對象。

  • 普通函數內的this情境
var id = 10;
let obj = {
      id: 15,
      fn: function(){
            setTimeout(function(){
                  alert(this.id); // 10
             },1000)
      }
}
obj.fn();

分析:1秒后執行window.setTimeout(),this指向window,因此返回的結果是全局下的id:10

如果想要獲取obj內的id,一般采用_this = this的辦法。

var id = 10;
let obj = {
      id: 15,
      fn: function(){
            _this = this; // 調用后,這里的this指向obj
            setTimeout(function(){
                  alert(_this.id); // 15
             },1000)
      }
}
obj.fn();
  • 箭頭函數內的this情境(1)
var id = 10;
let obj = {
      id: 15,
      fn: function(){
            setTimeout(()=>{
                  alert(this.id); 
             },1000)
      }
}
obj.fn(); // 15
obj.fn.call({id:123}); // 123

分析:setTimeout()中用了箭頭函數,因此箭頭函數內的this對象就固定在父級作用域下的this上。(這里就是函數fn)
也就是說,fn函數內的this指向了誰,箭頭函數的this就指向了誰。
當被obj調用時,fn函數的this指向了obj,所以返回obj下的id:15
當被對象{id:123}調用時,fn函數的this指向了{id:123},所以返回該對象下的id:123

  • 箭頭函數內的this情境(2)
var id = 10;
let obj = {
      id: 15,
      fn: ()=>{
            setTimeout(()=>{
                  alert(this.id); 
             },1000)
      }
}
obj.fn(); // 10
obj.fn.call({id:123}); // 10

分析:當obj下的fn方法也用箭頭函數,那么就會沿着作用域鏈往上找它的父級作用域的this,這里找到的是全局window。
於是this就固定在了window上,不管誰去調用它,它都只會返回window下的id:10

4.2 箭頭函數沒有arguments對象

普通函數在初始化的過程中,會產生一個arguments對象用來保存實參。
但是在箭頭函數中是不存在的,如果要使用實參列表,那么用rest參數來代替。

// 普通函數
let fn = function(a,b,c) {
      console.log(arguments);
}
fn(1,2,3);

// 箭頭函數
let bn = (...args)=> {
      console.log(args);
}
bn(1,2,3);

4.3 箭頭函數不可以用new實例化

let Person = (name)=> {
      this.name = name;
}
let p = new Person('mm'); // TypeError: Person is not a constructor

4.4 箭頭函數不可以使用yield命令

五、箭頭函數的使用場景

  • 當我們要維護一個this上下文環境時,就可以用箭頭函數。
var id = 10;
let obj = {
      id: 15,
      fn: function(){
            setTimeout(()=>{
                  alert(this.id); 
             },1000)
      }
}
obj.fn(); // 15
  • 定義對象方法,且要用到this時,不要用箭頭函數!
let person = {
      name: 'mm',
      say: ()=>{
            console.log(this.name); // 'gg'
      }
}
var name = 'gg';
person.say();
  • 監聽DOM事件時,不要用箭頭函數!
let box = document.getElementById('box');
box.addEventListener('click', function(){
      if(this.classList!='red') {
            this.classList = 'red';
      }else {
            this.classList = 'green';
      }
      console.log(this); // box
});

box.addEventListener('click', ()=>{
      if(this.classList!='red') {
            this.classList = 'red';
      }else {
            this.classList = 'green';
      }
      console.log(this); // window
});

六、總結

  1. 函數參數也可以解構賦值。
  2. 函數參數可以設置默認值,可以預設實參。
  3. 函數參數的默認值可以是函數調用。
  4. 箭頭函數的語法:參數=>函數體
  5. 箭頭函數的this是固定的,指向了父級作用域的this。
  6. 箭頭函數沒有arguments,可以用rest參數代替。
  7. 箭頭函數不可以new實例化。
  8. 箭頭函數不可以使用yield命令


免責聲明!

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



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