[OHIF-Viewers]醫療數字閱片-醫學影像-中間插播一下-es6-使用const加箭頭函數聲明函數相對于function聲明函數有什么好處?
[OHIF-Viewers]醫療數字閱片-醫學影像-中間插播一下-es6-使用const加箭頭函數聲明函數相對于function聲明函數有什么好處?
這個好多人都已經寫過了,這里插播一下,在OHIF-Viewers里面有很多這樣的寫法,當然OHIF-Viewers維護者眾多,有人用這種新的寫法也有原始的寫法,各種歷史遺留的寫法問題。
這是ES6中的東東,SO要搞REACT相關項目得先打好ES6基礎。
OHIF-Viewers項目,跟著博主此系列博文也可加快學習OHIF-Viewers的進度。
此前也寫了一篇[OHIF-Viewers]醫療數字閱片-醫學影像-ES6箭頭函數(=>)
ES6中,除了let和const新特性,箭頭函數是使用頻率最高的新特性了。如果你曾經了解如日中天的JavaScript衍生語言CoffeeScript, 就會清楚此特性并非ES6獨創。箭頭函數顧名思義是使用箭頭(=>)定義的函數,屬于匿名函數一類。
今天的文章內容將會從以下幾個方面,介紹箭頭函數:
- 使用語法
- this穿透
- 箭頭函數和傳統函數的區別
使用語法
箭頭函數有四種使用語法
1、單一參數的單行箭頭函數
如下段代碼所示,很簡單:
const fn= foo =>`${foo} world`;
這是箭頭函數最簡潔的形式,常用于用作簡單的處理函數,如過濾。如下段代碼所示:
let array=['a','bc','def','ghij'];
array=array.filter(item=>item.length>=2);
2、多參數的單行箭頭函數 語法也很簡單,如下段代碼所示:
const fn=(foo,bar) => foo+bar
在實際開發中,函數的參數不會只有一個,在箭頭函數中,多參數的語法跟普通函數一樣,用括號包裹參數項。我們經常處理函數,如排序,示例代碼如下:
let array=['a','bc','def','ghij'];
array=array.sort((a,b) => a.length < b.length);
3、多行箭頭函數 單一參數,如下段代碼所示:
foo => {
return `${foo} world`;
}
多參數,如下段代碼所示:
(foo,bar) => {
return foo+bar;
}
4、無參數箭頭函數
如果一個箭頭函數無參數傳入,則需要用一對空的括號來表示空的參數列表。
const greet = () => 'Hello World'
以上都是被支持的箭頭函數的表達方式,其最大的好處就是簡單明了,省略了function關鍵字,而使用 => 代替。相對于傳統的function函數,箭頭函數在簡單的函數使用中更為簡潔直觀。
書寫箭頭的函數過程中,我們應該注意以下幾點:
1、使用單行箭頭函數時,應避免換行
錯誤的用法,如下段代碼所示:
const fn=x
=> x*2 //SyntaxError
正確的寫法,如下:
const fn= x => x*2 //ok
2、參數列別的右括弧、箭頭應在一行
錯誤的用法,如下段代碼所示:
const fn = (x,y) //SyntaxError
=> {
return x*y;
}
下段代碼書寫是正確的:
const fn= (x,y) => { //ok
return x*y
}
const fn= (x,
y) => { //ok
return x*y
}
3、單行箭頭函數返回只能包含一條語句
錯誤的書寫,如下段代碼所示:
const fn1= x => x=x*2; return x+2; //SyntaxError
正確的書寫,如下段代碼所示:
const fn2= x => {
x=x*2;
return x+2;
} //ok
4、如果單行箭頭返回一個對象,請用圓括號包裹
錯誤的書寫,如下段代碼所示,解析引擎會將其解析成一個多行箭頭函數:
const ids=[1,2,3];
const users=ids.map(id=>{id:id});
//wrong:[ undefined, undefined, undefined ]
正確的書寫,如下段代碼所示:
const ids=[1,2,3];
const users=ids.map(id=>({id:id}));
//Correct:[ { id: 1 }, { id: 2 }, { id: 3 } ]
箭頭函數十分簡潔,特別適合單行回調函數的定義,比如我們有以下需求:
我們有一個這樣的名字數組names,['Will','Jack','Peter','Steve','John','Hugo','Mike'],輸出序號為偶數的名字[ 'Will', 'Peter', 'John', 'Mike' ],我們如何使用箭頭函數在一行語句完成呢,如下段代碼所示:
const names=['Will','Jack','Peter','Steve','John','Hugo','Mike'];
const newSet=names
.map((name,index)=>({
id:index,
name:name
}))
.filter(man => man.id %2 ==0)
.map(man => [man.name])
.reduce((a,b) => a.concat(b))
this穿透
事實上,箭頭函數不僅書寫簡潔,還有一個神奇的功能,就是將函數內部的this延伸上一層作用域中,及上一層的上下文會穿透到內層的箭頭函數中,讓我們先看一段實際的例子,如下段所示:
var Widget={
// A
init:function () {
// B
document.addEventListener("click", function (event){
//C
this.doSomething(event.type);
}, false);
},
doSomething:function (type) {
console.log("Handling"+ type+"event");
}
};
Widget.init();
這段代碼會如何輸出呢,想必大家都猜到了吧,輸出undefined,為什么呢?我們在B位置內聲明了函數(C區域),this關鍵詞的指向B區域的函數,由于B區域內沒有doSomething函數聲明,因此輸出undefined,ES6之前我們如何修正此問題呢?
我們可以使用bind方法改變this指向A區域Widget對象,示例代碼如下:
var Widget={
// A
init:function () {
// B
document.addEventListener("click", (function (event) {
//C
this.doSomething(event.type);
}).bind(this), false);
},
doSomething:function (type) {
console.log("Handling"+ type+"event");
}
};
Widget.init();
下面這種方法是我們最常用的方法,我們在B區域聲明了that變量,并將其this賦值,確保c區域this的指向至Widget對象:
var Widget={
// A
init:function () {
// B
var that=this;
document.addEventListener("click", function (event) {
//C
that.doSomething(event.type);
console.log(that);
}, false);
},
doSomething:function (type) {
console.log("Handling"+ type+"event");
}
};
Widget.init();
有了箭頭函數,我們可以使用箭頭函數的this穿透功能,將this的作用域延伸至上一層B區域函數,如下段代碼所示:
var Widget={
//A
init:function () {
//B
document.addEventListener("click", (event) => {
//C
this.doSomething(event.type);
}, false);
},
doSomething:function (type) {
console.log("Handling"+ type+"event");
}
};
Widget.init();
箭頭函數是不是更簡單,代碼更清晰呢。
還有一個情況需要注意,箭頭函數對上下文的綁定是強制的,無法通過call或aplly進行改變,如下段代碼所示:
function widget() {
this.id=123;
this.log=()=>{
console.log(this)
console.log('widget log',this.id);
}
}
var pseudoWidget={
id:456
};
new widget().log.call(pseudoWidget);//123
上述代碼會如何輸出呢,由于箭頭函數對上下文的綁定是強制的,因此this指向不會指向pseudoWidget對象,因此輸出123。
箭頭函數和傳統函數的區別
1、箭頭函數作為匿名函數,是不能作為構造函數的,不能使用new
如下段代碼所示,我們使用new方法,會提示如下信息:
const B =()=>({wechat:"前端達人"});
let b = new B(); //TypeError: B is not a constructor
2、箭頭函數不綁定arguments,可以使用剩余參數(rest)解決
function A(a){
console.log(arguments); //[object Arguments] {0: 1}
}
var B = (b)=>{
console.log(arguments); //ReferenceError: arguments is not defined
}
var C = (...c)=>{ //...c即為rest參數
console.log(c); //[3]
}
A(1);
B(2);
C(3);
3、箭頭函數this指向具備穿透特性,會捕獲其所在上下文的this值
4、箭頭函數沒有原型屬性
var a = ()=>{
return '前端達人';
}
function b(){
return '前端達人';
}
console.log(a.prototype);//undefined
console.log(b.prototype);//object{...}
5、箭頭函數不能當做Generator函數,不能使用yield關鍵字
6、箭頭函數對上下文的綁定是強制的,無法通過call或aplly進行改變
小節
今天的內容就介紹到這里,我們可以看出使用箭頭函能減少代碼量,更加簡介易讀。在使用箭頭函數時,我們一定要理解箭頭函數和傳統函數的區別,如果函數功能簡單,只是簡單的邏輯處理,盡量使用箭頭函數。
const 有什么好處?
- 不被覆蓋,被重寫會報錯,而函數聲明會安靜被覆蓋
函數表達式與函數聲明的對比?
- 前者需先前面寫好,明確往代碼前面找定義即可,后者可前可后,更靈活
- 前者可放塊Block語句中,搭配更豐富,后者不行
同是函數表達式?
- 相比function, 箭頭函數更簡潔,并自帶return,單個函數最多時節省14個字符(見回復2,
function+return+{}vs=>) - 箭頭函數常用于函數式編程/閉包場景,特別是頻繁在數組map、filter、reduce等中的使用
- 箭頭函數更易讀,更為主流,瀏覽器會往這方向優化
參考鏈接:

浙公網安備 33010602011771號