日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

箭头函数详解()=>{}

發布時間:2023/12/15 综合教程 19 生活家
生活随笔 收集整理的這篇文章主要介紹了 箭头函数详解()=>{} 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

摘要:箭頭函數有幾個使用注意點。

(1)函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象,箭頭函數繼承而來的this指向永遠不變。

(2)不可以當作構造函數,也就是說,不可以使用new命令,否則會拋出一個錯誤。

(3)不可以使用arguments對象,該對象在函數體內不存在。如果要用,可以用Rest參數代替。

(4)不可以使用yield命令,因此箭頭函數不能用作Generator函數。

一、基本語法

ES6中允許使用箭頭=>來定義箭頭函數,具體語法,我們來看一個簡單的例子:

// 箭頭函數
let fun = (name) => {
    // 函數體
    return `Hello ${name} !`;
};

// 等同于
let fun = function (name) {
    // 函數體
    return `Hello ${name} !`;
};

可以看出,定義箭頭函在數語法上要比普通函數簡潔得多。箭頭函數省去了function關鍵字,采用箭頭=>來定義函數。函數的參數放在=>前面的括號中,函數體跟在=>后的花括號中。

關于箭頭函數的參數:

①如果箭頭函數沒有參數,直接寫一個空括號即可。

②如果箭頭函數的參數只有一個,也可以省去包裹參數的括號。

③如果箭頭函數有多個參數,將參數依次用逗號(,)分隔,包裹在括號中即可。

// 沒有參數
let fun1 = () => {
    console.log(111);
};

// 只有一個參數,可以省去參數括號
let fun2 = name => {
    console.log(`Hello ${name} !`)
};

// 有多個參數
let fun3 = (val1, val2, val3) => {
    return [val1, val2, val3];
};

關于箭頭函數的函數體:

①如果箭頭函數的函數體只有一句代碼,就是簡單返回某個變量或者返回一個簡單的JS表達式,可以省去函數體的大括號{ }。

let f = val => val;
// 等同于
let f = function (val) { return val };

let sum = (num1, num2) => num1 + num2;
// 等同于
let sum = function(num1, num2) {
  return num1 + num2;
};

②如果箭頭函數的函數體只有一句代碼,就是返回一個對象,可以像下面這樣寫:

// 用小括號包裹要返回的對象,不報錯
let getTempItem = id => ({ id: id, name: "Temp" });

// 但絕不能這樣寫,會報錯。
// 因為對象的大括號會被解釋為函數體的大括號
let getTempItem = id => { id: id, name: "Temp" };

③如果箭頭函數的函數體只有一條語句并且不需要返回值(最常見是調用一個函數),可以給這條語句前面加一個void關鍵字

let fn = () => void doesNotReturn();

箭頭函數最常見的用處就是簡化回調函數。

// 例子一
// 正常函數寫法
[1,2,3].map(function (x) {
  return x * x;
});

// 箭頭函數寫法
[1,2,3].map(x => x * x);

// 例子二
// 正常函數寫法
var result = [2, 5, 1, 4, 3].sort(function (a, b) {
  return a - b;
});

// 箭頭函數寫法
var result = [2, 5, 1, 4, 3].sort((a, b) => a - b);

二、箭頭函數與普通函數的區別

1、語法更加簡潔、清晰

從上面的基本語法示例中可以看出,箭頭函數的定義要比普通函數定義簡潔、清晰得多,很快捷。

2、箭頭函數不會創建自己的this(重要!!深入理解!!)

我們先來看看MDN上對箭頭函數this的解釋。

箭頭函數不會創建自己的this,所以它沒有自己的this,它只會從自己的作用域鏈的上一層繼承this。

箭頭函數沒有自己的this,它會捕獲自己在定義時(注意,是定義時,不是調用時)所處的外層執行環境的this,并繼承這個this值。所以,箭頭函數中this的指向在它被定義的時候就已經確定了,之后永遠不會改變。

來看個例子:

var id = 'Global';

function fun1() {
    // setTimeout中使用普通函數
    setTimeout(function(){
        console.log(this.id);
    }, 2000);
}

function fun2() {
    // setTimeout中使用箭頭函數
    setTimeout(() => {
        console.log(this.id);
    }, 2000)
}

fun1.call({id: 'Obj'});     // 'Global'

fun2.call({id: 'Obj'});     // 'Obj'

上面這個例子,函數fun1中的setTimeout中使用普通函數,2秒后函數執行時,這時函數其實是在全局作用域執行的,所以this指向Window對象,this.id就指向全局變量id,所以輸出'Global'
但是函數fun2中的setTimeout中使用的是箭頭函數,這個箭頭函數的this在定義時就確定了,它繼承了它外層fun2的執行環境中的this,而fun2調用時thiscall方法改變到了對象{id: 'Obj'}中,所以輸出'Obj'

再來看另一個例子:

var id = 'GLOBAL';
var obj = {
  id: 'OBJ',
  a: function(){
    console.log(this.id);
  },
  b: () => {
    console.log(this.id);
  }
};

obj.a();    // 'OBJ'
obj.b();    // 'GLOBAL'

上面這個例子,對象obj的方法a使用普通函數定義的,普通函數作為對象的方法調用時,this指向它所屬的對象。所以,this.id就是obj.id,所以輸出'OBJ'
但是方法b是使用箭頭函數定義的,箭頭函數中的this實際是繼承的它定義時所處的全局執行環境中的this,所以指向Window對象,所以輸出'GLOBAL'。(這里要注意,定義對象的大括號{}是無法形成一個單獨的執行環境的,它依舊是處于全局執行環境中!!)

3、箭頭函數繼承而來的this指向永遠不變(重要!!深入理解!!)

上面的例子,就完全可以說明箭頭函數繼承而來的this指向永遠不變。對象obj的方法b是使用箭頭函數定義的,這個函數中的this就永遠指向它定義時所處的全局執行環境中的this,即便這個函數是作為對象obj的方法調用,this依舊指向Window對象。

4、.call()/.apply()/.bind()無法改變箭頭函數中this的指向

.call()/.apply()/.bind()方法可以用來動態修改函數執行時this的指向,但由于箭頭函數的this定義時就已經確定且永遠不會改變。所以使用這些方法永遠也改變不了箭頭函數this的指向,雖然這么做代碼不會報錯。

var id = 'Global';
// 箭頭函數定義在全局作用域
let fun1 = () => {
    console.log(this.id)
};

fun1();     // 'Global'
// this的指向不會改變,永遠指向Window對象
fun1.call({id: 'Obj'});     // 'Global'
fun1.apply({id: 'Obj'});    // 'Global'
fun1.bind({id: 'Obj'})();   // 'Global'

5、箭頭函數不能作為構造函數使用

我們先了解一下構造函數的new都做了些什么?簡單來說,分為四步:

① JS內部首先會先生成一個對象;

② 再把函數中的this指向該對象;

③ 然后執行構造函數中的語句;

④ 最終返回該對象實例。

但是!!因為箭頭函數沒有自己的this,它的this其實是繼承了外層執行環境中的this,且this指向永遠不會隨在哪里調用、被誰調用而改變,所以箭頭函數不能作為構造函數使用,或者說構造函數不能定義成箭頭函數,否則用new調用時會報錯!

let Fun = (name, age) => {
    this.name = name;
    this.age = age;
};

// 報錯
let p = new Fun('cao', 24);

6、箭頭函數沒有自己的arguments

箭頭函數沒有自己的arguments對象。在箭頭函數中訪問arguments實際上獲得的是外層局部(函數)執行環境中的值。

// 例子一
let fun = (val) => {
    console.log(val);   // 111
    // 下面一行會報錯
    // Uncaught ReferenceError: arguments is not defined
    // 因為外層全局環境沒有arguments對象
    console.log(arguments); 
};
fun(111);

// 例子二
function outer(val1, val2) {
    let argOut = arguments;
    console.log(argOut);    // ①
    let fun = () => {
        let argIn = arguments;
        console.log(argIn);     // ②
        console.log(argOut === argIn);  // ③
    };
    fun();
}
outer(111, 222);

上面例子二,①②③處的輸出結果如下:

很明顯,普通函數outer內部的箭頭函數fun中的arguments對象,其實是沿作用域鏈向上訪問的外層outer函數的arguments對象。

可以在箭頭函數中使用rest參數代替arguments對象,來訪問箭頭函數的參數列表!!

7、箭頭函數沒有原型prototype

let sayHi = () => {
    console.log('Hello World !')
};
console.log(sayHi.prototype); // undefined

8、箭頭函數不能用作Generator函數,不能使用yeild關鍵字

9、箭頭函數位于構造函數內部,它的定義生效的時候,是在構造函數執行的時候。這時,箭頭函數所在的運行環境,肯定是實例對象,所以this會總是指向實例對象。

總結

以上是生活随笔為你收集整理的箭头函数详解()=>{}的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。