电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

JS什么場景不適合箭頭函數

瀏覽:112日期:2024-03-31 08:01:35
概述

這些年來,ES6 將js的可用性提升到一個新的水平時: 箭頭函數、類等等,這些都很棒。

箭頭函數是最有價值的新功能之一,有很多好文章描述了它的上下文透明性和簡短的語法。

但每個事務都有兩面。通常,新特性會帶來一些混亂,其中之一就是箭頭函數被誤導了。本文將介紹一些場景,在這些場景中,你應該繞過箭頭函數,轉而使用良好的舊函數表達式或較新的簡寫語法。并且要注意縮短代碼,因為這會影響代碼的可讀性。

定義對象上的方法

在js中,方法是存儲在對象屬性中的函數。當調用該方法時,this將指向該方法所屬的對象。

Object literal

由于箭頭函數語法簡短,所以使用它來定義方法是很有吸引力的,讓咱們來試一試:

const calculate = { array: [1, 2, 3], sum: () => { console.log(this === window); // => true return this.array.reduce((result, item) => result + item); }};console.log(this === window); // => true// Throws 'TypeError: Cannot read property ’reduce’ of undefined'calculate.sum();

calculate.sum方法用箭頭函數定義。 但是在調用時,calculate.sum()會拋出一個TypeError,因為this.array為undefined。

當調用calculate對象上的方法sum()時,上下文仍然是window。之所以會發生這種情況,是因為箭頭函數按詞法作用域將上下文綁定到window對象。

執行this.array等同于window.array,它是undefined。

解決方法是使用常規函數表達式來定義方法。 this 是在調用時確定的,而不是由封閉的上下文決定的,來看看修復后的版本:

const calculate = { array: [1, 2, 3], sum() { console.log(this === calculate); // => true return this.array.reduce((result, item) => result + item); }};calculate.sum(); // => 6

因為sum是常規函數,所以在調用calculate.sum()時this是calculate對象。this.array是數組引用,因此正確計算元素之和:6。

Object prototype

同樣的規則也適用于在原型對象上定義方法。使用一個箭頭函數來定義sayCatName方法,this指向window

function MyCat(name) { this.catName = name;}MyCat.prototype.sayCatName = () => { console.log(this === window); // => true return this.catName;};const cat = new MyCat(’Mew’);cat.sayCatName(); // => undefined

使用早期的方式定義函數表達式:

function MyCat(name) { this.catName = name;}MyCat.prototype.sayCatName = function() { console.log(this === cat); // => true return this.catName;};const cat = new MyCat(’Mew’);cat.sayCatName(); // => ’Mew’

sayCatName常規函數在作為方法調用時將上下文更改為cat對象:cat.sayCatName()。

動態上下文的回調函數

this在JS中是一個強大的特性,它允許根據調用函數的方式更改上下文。通常,上下文是調用發生的目標對象,這使得代碼更加自然,就像這個對象發生了什么。

但是,箭頭函數會在聲明上靜態綁定上下文,并且無法使其動態化,但這種方式有壞也有好,有時候我們需要動態綁定。

在客戶端編程中,將事件偵聽器附加到DOM元素是一項常見的任務。事件觸發處理程序函數,并將this作為目標元素,這里如果使用箭頭函數就不夠靈活。

下面的示例嘗試為這樣的處理程序使用箭頭函數:

const button = document.getElementById(’myButton’);button.addEventListener(’click’, () => { console.log(this === window); // => true this.innerhtml = ’Clicked button’;});

在全局上下文中this指向window。 當發生單擊事件時,瀏覽器嘗試使用按鈕上下文調用處理函數,但箭頭函數不會更改其預定義的上下文。this.innerhtml相當于window.innerHTML,沒有任何意義。

必須應用函數表達式,該表達式允許根據目標元素更改this:

const button = document.getElementById(’myButton’);button.addEventListener(’click’, function() { console.log(this === button); // => true this.innerHTML = ’Clicked button’;});

當用戶單擊按鈕時,處理程序函數中的this指向button。因此這個問題。innerHTML = ’Clicked button’正確地修改按鈕文本以反映已單擊狀態。

調用構造函數

this在構造調用中是新創建的對象。當執行new MyFunction()時,構造函數MyFunction的上下文是一個新對象:this instanceof MyFunction === true。

注意,箭頭函數不能用作構造函數。JavaScript通過拋出異常隱式阻止這樣做。

無論如何,this是來自封閉上下文的設置,而不是新創建的對象。換句話說,箭頭函數構造函數調用沒有意義,而且是模糊的。

讓我們看看如果嘗試這樣做會發生什么:

const Message = (text) => { this.text = text;};// Throws 'TypeError: Message is not a constructor'const helloMessage = new Message(’Hello World!’);

執行new Message(’Hello World!’),其中Message是一個箭頭函數,JavaScript拋出一個TypeError錯誤,Message不能用作構造函數。

上面的例子可以使用函數表達式來修復,這是創建構造函數的正確方法(包括函數聲明):

const Message = function(text) { this.text = text;};const helloMessage = new Message(’Hello World!’);簡寫語法

箭頭函數有一個很好的屬性,它可以省略參數圓括號()、塊大括號{},如果函數主體只有一條語句,則返回。這有助于編寫非常短的函數。

原文作者的大學編程教授給學生一個有趣的任務:編寫 用C語言計算字符串長度的最短函數,這是學習和探索新語言的好方式。

然而,在實際應用程序中,許多開發人員都會閱讀代碼。 最短的語法并不總是適合幫助你的同事即時了解該方法的用途。

在某種程度上,簡寫的函數變得難以閱讀,所以盡量不要過度使用。讓各位們看一個例子

const multiply = (a, b) => b === undefined ? b => a * b : a * b;const double = multiply(2);double(3); // => 6multiply(2, 3); // => 6

multiply返回兩個數字的乘法結果或與第一個參數綁定的閉包,以便以后的乘法運算。

該函數運行良好,看起來很短。但從一開始就很難理解它是做什么的。

為了使其更具可讀性,可以從箭頭函數恢復可選花括號和return語句,或使用常規函數:

function multiply(a, b) { if (b === undefined) { return function(b) { return a * b; } } return a * b;}const double = multiply(2);double(3); // => 6multiply(2, 3); // => 6

在簡短和冗長之間找到一個平衡點是很好的,這樣可以使代碼更加直觀。

總結

毫無疑問,箭頭函數是一個很好的補充。當正確使用時,它會使前面必須使用.bind()或試圖捕獲上下文的地方變得簡單,它還簡化了代碼。

某些情況下的優點會給其他情況帶來不利。 當需要動態上下文時,不能使用箭頭函數:定義方法,使用構造函數創建對象,在處理事件時從this獲取目標。

以上就是JS什么場景不適合箭頭函數的詳細內容,更多關于JS的資料請關注好吧啦網其它相關文章!

標簽: JavaScript
相關文章:
主站蜘蛛池模板: 万濠投影仪_瑞士TRIMOS高度仪_尼康投影仪V12BDC|量子仪器 | 智慧水务|智慧供排水利信息化|水厂软硬件系统-上海敢创 | 冷柜风机-冰柜电机-罩极电机-外转子风机-EC直流电机厂家-杭州金久电器有限公司 | 台湾阳明固态继电器-奥托尼克斯光电传感器-接近开关-温控器-光纤传感器-编码器一级代理商江苏用之宜电气 | 小港信息港-鹤壁信息港 鹤壁老百姓便民生活信息网站 | 【MBA备考网】-2024年工商管理硕士MBA院校/报考条件/培训/考试科目/提前面试/考试/学费-MBA备考网 | 安平县鑫川金属丝网制品有限公司,声屏障,高速声屏障,百叶孔声屏障,大弧形声屏障,凹凸穿孔声屏障,铁路声屏障,顶部弧形声屏障,玻璃钢吸音板 | 奇酷教育-Python培训|UI培训|WEB大前端培训|Unity3D培训|HTML5培训|人工智能培训|JAVA开发的教育品牌 | 焊管生产线_焊管机组_轧辊模具_焊管设备_焊管设备厂家_石家庄翔昱机械 | 煤机配件厂家_刮板机配件_链轮轴组_河南双志机械设备有限公司 | 真石漆,山东真石漆,真石漆厂家,真石漆价格-山东新佳涂料有限公司 | 玻纤土工格栅_钢塑格栅_PP焊接_单双向塑料土工格栅_复合防裂布厂家_山东大庚工程材料科技有限公司 | EFM 022静电场测试仪-套帽式风量计-静电平板监测器-上海民仪电子有限公司 | 塑料脸盆批发,塑料盆生产厂家,临沂塑料广告盆,临沂家用塑料盆-临沂市永顺塑业 | ETFE膜结构_PTFE膜结构_空间钢结构_膜结构_张拉膜_浙江萬豪空间结构集团有限公司 | 生产自动包装秤_颗粒包装秤_肥料包装秤等包装机械-郑州鑫晟重工科技有限公司 | 企业彩铃制作_移动、联通、电信集团彩铃上传开通_彩铃定制_商务彩铃管理平台-集团彩铃网 | 对辊式破碎机-对辊制砂机-双辊-双齿辊破碎机-巩义市裕顺机械制造有限公司 | 青岛代理记账_青岛李沧代理记账公司_青岛崂山代理记账一个月多少钱_青岛德辉财税事务所官网 | 螺钉式热电偶_便携式温度传感器_压簧式热电偶|无锡联泰仪表有限公司|首页 | 上海盐水喷雾试验机_两厢式冷热冲击试验箱-巨怡环试 | 隔爆型防爆端子分线箱_防爆空气开关箱|依客思 | 武汉天安盾电子设备有限公司 - 安盾安检,武汉安检门,武汉安检机,武汉金属探测器,武汉测温安检门,武汉X光行李安检机,武汉防爆罐,武汉车底安全检查,武汉液体探测仪,武汉安检防爆设备 | 铝合金线槽_铝型材加工_空调挡水板厂家-江阴炜福金属制品有限公司 | 自进式锚杆-自钻式中空注浆锚杆-洛阳恒诺锚固锚杆生产厂家 | 皮带机_移动皮带机_大倾角皮带机_皮带机厂家 - 新乡市国盛机械设备有限公司 | 河南砖机首页-全自动液压免烧砖机,小型砌块水泥砖机厂家[十年老厂] | TPU薄膜_TPU薄膜生产厂家_TPU热熔胶膜厂家定制_鑫亘环保科技(深圳)有限公司 | 雷冲击高压发生器-水内冷直流高压发生器-串联谐振分压器-武汉特高压电力科技有限公司 | 淄博不锈钢无缝管,淄博不锈钢管-鑫门物资有限公司 | 北京中航时代-耐电压击穿试验仪厂家-电压击穿试验机 | 英国公司注册-新加坡公司注册-香港公司开户-离岸公司账户-杭州商标注册-杭州优创企业 | 卧涛科技有限公司科技项目申报公司|高新技术企业申报|专利申请 | 施工围挡-施工PVC围挡-工程围挡-深圳市旭东钢构技术开发有限公司 | 兰州UPS电源,兰州山特UPS-兰州万胜商贸| 新密高铝耐火砖,轻质保温砖价格,浇注料厂家直销-郑州荣盛窑炉耐火材料有限公司 | 纸箱抗压机,拉力机,脂肪测定仪,定氮仪-山东德瑞克仪器有限公司 | 翰墨AI智能写作助手官网_人工智能问答在线AI写作免费一键生成 | 深圳善跑体育产业集团有限公司_塑胶跑道_人造草坪_运动木地板 | 电力测功机,电涡流测功机,磁粉制动器,南通远辰曳引机测试台 | 细石混凝土泵_厂家_价格-烟台九达机械有限公司 |