目錄
執行環境" >執行環境
一個新主題" >一個新主題
新的語法" >新的語法
箭頭函數是怎麼實作的
" >箭頭函數是怎麼實作的
#立即執行函數(IIFE)" >#立即執行函數(IIFE)
" >#相關思考
" >作用域
有趣和有用的使用" >有趣和有用的使用
推荐的链接" >推荐的链接
总结" >总结
首頁 web前端 js教程 了解ES6中的箭頭函數極為作用域

了解ES6中的箭頭函數極為作用域

Oct 29, 2020 pm 06:02 PM
es6 javascript 箭頭函數

了解ES6中的箭頭函數極為作用域

在ES6很多很棒的新特性中, 箭頭函數(或大箭頭函數)就是其中值得關注的一個! 它不僅僅是很棒很酷, 它很好的利用了作用域, 快捷方便的在現在使用以前我們用的技術, 減少了很多代碼......但是如果你不了解箭頭函數原理的話可能就有點難以理解. 所以,讓我們來看下箭頭函數, 就是現在!

執行環境

你可以自己去學習和嘗試下, 你可以簡單的把範例程式碼複製到你的瀏覽器控制台下. 現在, 推薦使用Firefox(22 )開發者工具, Firefox(22 )開發者工具現在支持箭頭函數,你也可以使用谷歌瀏覽器. 如果你使用谷歌瀏覽器, 你必須要做下列兩件事:

  • 在Google瀏覽器中網址列輸入:about:flags, 找到"使用體驗性JavaScript"選項,開啟使用。

  • 在函數的開頭加上use strict,然後再在你的谷歌瀏覽中測試箭頭函數吧(提示:請用谷歌瀏覽器v38,我當時就是被瀏覽器版本坑了):

(function(){
    "use strict";
    // use arrow functions here
}());
登入後複製

幸運的是後面會有越來越多的瀏覽器支援ES6特性. 現在你完成了所有準備工作, 讓我們繼續深入它吧!

一個新主題

最近大家在討論關於ES6的一個主題:關於箭頭函數, 像這樣:

=>
登入後複製

新的語法

隨著討論產生了一個新的語法:

param => expression
登入後複製

新增的語法是作用在變數上, 可以在表達式中申明多個變數, 下面是箭頭函數的使用模式:

//  一个参数对应一个表达式
param => expression;// 例如 x => x+2;

// 多个参数对应一个表达式
(param [, param]) => expression; //例如 (x,y) => (x + y);

// 一个参数对应多个表示式
param => {statements;} //例如 x = > { x++; return x;};

//  多个参数对应多个表达式
([param] [, param]) => {statements} // 例如 (x,y) => { x++;y++;return x*y;};

//表达式里没有参数
() => expression; //例如var flag = (() => 2)(); flag等于2
() => {statements;} //例如 var flag = (() => {return 1;})(); flag就等于1

//传入一个表达式,返回一个对象
([param]) => ({ key: value });
//例如  var fuc = (x) => ({key:x})
        var object = fuc(1);
        alert(object);//{key:1}
登入後複製

箭頭函數是怎麼實作的

我們可以把一個普通函數轉換成用箭頭函數來實作:

// 当前函数
var func = function (param) {
    return param.split(" ");
}
// 利用箭头函数实现
var func = param => param.split(" ");
登入後複製

從上面的例子我們可以看出箭頭函數的語法實際上是返回了一個新的函數, 這個函數有函數體和參數。

因此, 我們可以這樣呼叫剛才我們所建立的函數:

func("Felipe Moura"); // returns ["Felipe", "Moura"]
登入後複製

#立即執行函數(IIFE)

##你能在立即執行函數裡使用箭頭函數,例如:

( x => x * 2 )( 3 ); // 6
登入後複製

這行程式碼產生了一個臨時函數,這個函數有一個形參x,函數的返回值為x*2,之後系統會馬上執行這個臨時函數, 將3賦值給形參x.

下面的例子描述了臨時函數體裡有多行程式碼的情況:

( (x, y) => {
    x = x * 2;
    return x + y;
})( 3, "A" ); // "6A"
登入後複製

#相關思考

思考下面的函數:

var func = x => {
    return x++;
};
登入後複製

我們列出了一些常見的問題:

箭頭函數所建立的暫存函數的arguments它不會被置:

console.log(arguments); // not defined
登入後複製

typeofinstanceof函數也能正常檢查臨時函數:

func instanceof Function; // true
typeof func; // function
func.constructor == Function; // true
登入後複製

把箭頭函數放在括號內是無效的:

//  有效的常规语法
(function (x, y){
    x= x * 2;
    return x + y;
} (3, "B") );
// 无效的箭头函数语法
( (x, y) => {
    x= x * 2;
    return x + y;
} ( 3, "A" ) );
// 但是可以这样写就是有效的了:
( (x,y) => {
    x= x * 2;return x + y;
} )( 3,"A" );//立即执行函数
登入後複製

儘管箭頭函數會產生一個臨時函數,但是這個臨時函數不是一個建構函數:

var instance= new func(); // TypeError: func is not a constructor
登入後複製

同樣也沒有原型物件:

func.prototype; // undefined
登入後複製

作用域

這個箭頭函數的作用域和其他函數有一些不同,如果不是嚴格模式,this關鍵字就是指向window,嚴格模式就是undefined,在構造函數裡的this指向的是當前對象實例,如果this在一個對象的函數內則this指向的是這個對象,this有可能指向的是一個DOM元素,例如當我們添加事件監聽函數時,可能這個this的指向不是很直接,其實this(不止是this變量)變量的指向是根據一個規則來判斷的:作用域流。下面我將示範this在事件監聽函數和在物件函數內出現的情況:

在事件監聽函數中:

document.body.addEventListener('click', function(evt){
    console.log(this); // the HTMLBodyElement itself
});
登入後複製

在建構子裡:

function Person () {
    let fullName = null;
    this.getName = function () {
        return fullName;
    };
    this.setName = function (name) {
        fullName = name;
        return this;
    };
}
let jon = new Person();
jon.setName("Jon Doe");
console.log(jon.getName()); // "Jon Doe"
//注:this关键字这里就不解释了,大家自己google,baidu吧。
登入後複製

在這個範例中,如果我們讓Person.setName函數傳回Person物件本身,我們就可以這樣用:

jon.setName("Jon Doe")
.getName(); // "Jon Doe"
登入後複製

在一個物件裡:

let obj = {
    foo: "bar",
    getIt: function () {
        return this.foo;
    }
};
console.log( obj.getIt() ); // "bar"
登入後複製

但是當執行流(比如使用了setTimeout )和作用域變了的時候,this也會變。

function Student(data){
    this.name = data.name || "Jon Doe";
    this.age = data.age>=0 ? data.age : -1;
    this.getInfo = function () {
        return this.name + ", " + this.age;
    };
    this.sayHi = function () {
        window.setTimeout( function () {
            console.log( this );
        }, 100 );
    }
}

let mary = new Student({
    name: "Mary Lou",
    age: 13
});
console.log( mary.getInfo() ); // "Mary Lou, 13"
mary.sayHi();
// window
登入後複製

當setTimeout函數改變了執行流的情況時,this的指向會變成全局對象,或者是在嚴格模式下就是undefine,這樣在setTimeout函數裡面我們使用其他的變量去指向this對象,例如self,that,當然不管你用什麼變量,你首先應該在setTimeout訪問之前,給self,that賦值,或者使用bind方法不然這些變量就是undefined。

這是後就是箭頭函數登場的時候了,它可以保持作用域,this的指向就不會變了。

讓我們看上文起先的例子,在這裡我們使用箭頭函數:

function Student(data){
    this.name = data.name || "Jon Doe";
    this.age = data.age>=0 ? data.age : -1;
    this.getInfo = function () {
        return this.name + ", " + this.age;
    };
    this.sayHi = function () {
        window.setTimeout( ()=>{
            // the only difference is here
            console.log( this );
        }, 100 );
    }
}

let mary = new Student({
    name: "Mary Lou",
    age: 13
});
console.log( mary.getInfo() ); // "Mary Lou, 13"
mary.sayHi();
// Object { name: "Mary Lou", age: 13, ... }
登入後複製

分析:在sayHi函數中,我們使用了箭頭函數,目前作用域是在student物件的一個方法中,箭頭函數產生的暫存函數的作用域也就是student物件的sayHi函數的作用域。所以即使我們在setTimeout呼叫了箭頭函數產生的臨時函數,這個臨時函數中的this也是正確的指向。

有趣和有用的使用

创建一个函数很容易,我们可以利用它可以保持作用域的特征:

例如我们可以这么使用:Array.forEach()

var arr = ['a', 'e', 'i', 'o', 'u'];
arr.forEach(vowel => {
    console.log(vowel);
});
登入後複製

分析:在forEach里箭头函数会创建并返回一个临时函数 tempFun,这个tempFun你可以想象成这样的:function(vowel){ console.log(vowel);}但是Array.forEach函数会怎么去处理传入的tempFunc呢?在forEach函数里会这样调用它:tempFunc.call(this,value);所有我们看到函数的正确执行效果。

//在Array.map里使用箭头函数,这里我就不分析函数执行过程了。。。。

var arr = ['a', 'e', 'i', 'o', 'u'];
arr.map(vowel => {
    return vowel.toUpperCase();
});
// [ "A", "E", "I", "O", "U" ]
登入後複製

费布拉奇数列

var factorial = (n) => {
    if(n==0) {
        return 1;
    }
    return (n * factorial (n-1) );
}
factorial(6); // 720
登入後複製

我们也可以用在Array.sort方法里:

let arr = ['a', 'e', 'i', 'o', 'u'];
arr.sort( (a, b)=> a < b? 1: -1 );
登入後複製

也可以在事件监听函数里使用:

// EventObject, BodyElement
document.body.addEventListener('click', event=>console.log(event, this));
登入後複製

推荐的链接

下面列出了一系列有用的链接,大家可以去看一看

总结

尽管大家可能会认为使用箭头函数会降低你代码的可读性,但是由于它对作用域的特殊处理,它能让我们能很好的处理this的指向问题。箭头函数加上let关键字的使用,将会让我们JavaScript代码上一个层次!尽量多使用箭头函数,你可以再你的浏览器测试你写的箭头函数代码,大家可以再评论区留下你对箭头函数的想法和使用方案!我希望大家能享受这篇文章,就像你会不就的将来享受箭头函数带给你的快乐.

相关免费学习推荐:js视频教程

更多编程相关知识,请访问:编程入门!!

以上是了解ES6中的箭頭函數極為作用域的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1319
25
PHP教程
1269
29
C# 教程
1248
24
如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

javascript如何使用insertBefore javascript如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

JavaScript與WebSocket:打造高效率的即時影像處理系統 JavaScript與WebSocket:打造高效率的即時影像處理系統 Dec 17, 2023 am 08:41 AM

JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數

See all articles