{}
大括號省略。
{}
是作為箭頭函式裡面的程式碼片段的範圍使用,並不是物件實字中使用的{}
大括號。所以如果箭頭函式要回傳一個物件內容,須於 {}
外層加上 ()
包覆 → ({})
。{}
大括號 & return
」。()
括號,但如果沒有參數要保留 ()
括號。{}
大括號 & return
。// 箭頭函式回傳裡面的物件
const ArrFn = () => ({
data:1
});
console.log(ArrFn());
// 箭頭函式未縮寫
const numB = (x) => {
return x * x;
};
console.log(numB(3));
// 箭頭函式縮寫 "return和大括號"可拿掉
const numB = (x) => x * x;
console.log(numB(3));
const numC = (x) => `數字相乘等於 ${x * x}`;
console.log(numC(3));
// 箭頭函式縮寫-沒有參數
const numD = () => `數字只能是 ${9}`
console.log(numD());
argument
這個參數。this
,所以它的 this
會指向它的外層。call
, apply
, bind
重新給予 this
。argument
這個參數傳統函式在執行時會自動帶上 argument
這個參數,但箭頭函式沒有 argument
這個參數。
範例 1. 傳統函式
const nums = function() {
console.log(arguments);
}
nums(10, 50, 60, 5, 6);
範例 2. 箭頭函式
const nums = () => {
console.log(arguments);
}
nums(10, 50, 60, 5, 6);
會顯示錯誤訊息 Uncaught ReferenceError: arguments is not defined at nums
➤ 其餘參數:解決箭頭函式沒有 argument
的方式
有時候也會遇到想要取出沒列出的參數,可使用「 其餘參數 」的方式 …變數名稱
。
const nums = (...ary) => {
console.log(ary);
}
nums(10, 50, 60, 5, 6);
argument
參數有些微不同。箭頭函式沒有自己的 this
,所以它的 this
會指向它外層。
範例 1.
var myName = '全域';
var person = {
myName: '小明',
callName: function() {
console.log('1', this.myName);
setTimeout(()=> {
console.log('2', this.myName);
console.log('3', this);
},10);
},
}
person.callName();
解析:
因為箭頭函式沒有自己的 this
,所以 setTimeout
裡的 this
就會指向它外層的 person
下的 myName
。
範例 2.
var myName = '全域';
var person = {
myName: '小明',
callName: () => {
console.log('1', this.myName);
setTimeout(()=> {
console.log('2', this.myName);
console.log('3', this.myName);
},10);
},
}
person.callName();
解析:
callName
調整成箭頭函式,因為箭頭函式沒有自己的 this
,所以會往外找外層的 myName
。全域
,3 為 window。範例 3. this 不同,導致 DOM 的 this 也會指向不同位置
// 使用傳統函式
const el = document.querySelector('p');
el.addEventListener('click', function() {
console.log(this);
});
this
會指向 p
段落。// 使用箭頭函式
const el = document.querySelector('p');
el.addEventListener('click', () => {
console.log(this);
});
this
會指向 window
,因為箭頭函式沒有自己的 this
它會指向外層。const family = {
myName: '小明家',
}
// const fn = function (para1, para2) {
// console.log(this, para1, para2);
// }
const fn = (para1, para2) => {
console.log(this, para1, para2);
}
fn.call(family, '小明', '杰倫');
call
可把另外一段函式傳入,作為它的還是函式執行的 this
。family
用 call
的方式傳入,this
會指向全域,因為箭頭函式的 this
無法透過 call
, apply
, bind
重新給予。範例 1. 查看傳統函式與箭頭函式的 prototype ( 原型 )
const Fn = function (a) {
this.name = a;
}
const ArrowFn = (a) => {
this.name = a;
}
console.log(Fn.prototype);
console.log(ArrowFn.prototype);
const a = new Fn('a');
console.log(a);
const b = new ArrowFn('b');
console.log(b);
prototype
來新增一些方法,但因「 箭頭函式不具有 prototype
所以是不能拿來當建構函式使用 」。所以當 ArrowFn
要新建建構函式就會出現錯誤訊息 Uncaught TypeError: ArrowFn is not a constructor
。關於建構式可參考:鐵人賽:JavaScript 建構式
const ArrFn = () => {
data: 1,
};
console.log(ArrFn());
此方式不能直接回傳物件實字,會顯示錯誤訊息:Uncaught SyntaxError: Unexpected token '}’
箭頭函式後的 {}
是作為箭頭函式裡面的程式碼片段的範圍使用,並不是物件實字中使用的{}
大括號。所以如果箭頭函式要回傳一個物件內容,須於 {}
外層加上 ()
包覆 → ({})
。
// 正確寫法
const ArrFn = () => ({
data: 1,
});
console.log(ArrFn()); // 就可正確回傳裡面的物件
let num = 0;
const numFn = num || () => 1;
console.log(numFn());
這種判斷式後方不能使用箭頭函式,會出現錯誤訊息 Uncaught SyntaxError: Malformed arrow function parameter list
。
正確寫法需使用傳統函式或是如上一個範例用 ()
包覆。
// 正確寫法 --1
// numFn 右方的 num 是假值(上方定義 num為0所以會直接執行後方函式),回傳函式表達式中的 1
let num = 0;
const numFn = num || function() { return 1; }
console.log(numFn());
// 正確寫法 --2
let num = 0;
const numFn = num || (() => 1);
console.log(numFn());
const person = {
myName: '小明',
callName: () => {
console.log(this.myName);
}
}
person.callName();
會印出 undefined
。因為箭頭函式沒有自己的 this
, callName
使用箭頭函式裡面的 this
會指向全域,全域並沒有 muName
。所以如果要取得小明
,callName
就要使用傳統函式。
const person = {
myName: '小明',
callName: function (){
console.log(this.myName);
}
}
person.callName();
const Fn2 = function (a) {
this.name = a;
}
Fn2.prototype.protoFn = () => {
return this.name;
}
// 實體化
const newObj = new Fn2('函式');
console.log(newObj);
console.log(newObj.protoFn());
第一行使用傳統函式作建構函式使用。第二行在 Fn2
函式的 prototype
下新增一個原型方法 protoFn
,這個原型方法使用建構函式來建立。
console.log(newObj);
可正確查到 Fn2
原型 (prototype
) 下的 protoFn
方法。但實際在執行時 console.log(newObj.protoFn());
所得到的值會是空的。
為什麼無法得到 newObj
下面的 name
,而是取到空值?
主要是箭頭函式指向和傳統函式不同,所以 Fn2.prototype.protoFn
裡的 this
指向是全域 window
而非第一行 Fn2
。
const Fn2 = function (a) {
this.name = a;
}
// 調整程式碼看看裡面的this
Fn2.prototype.protoFn = () => {
return this;
}
// 實體化
const newObj = new Fn2('函式');
console.log(newObj.protoFn()); // window
正確寫法,把 Fn2.prototype.protoFn
使用傳統函式來建構,可見 this
指向為第一行的 Fn2
。
const Fn2 = function (a) {
this.name = a;
}
Fn2.prototype.protoFn = function() {
return this;
}
// 實體化
const newObj = new Fn2('函式');
console.log(newObj.protoFn());
// 陣列雙倍
const arr = [15, 12, 63, 67, 1421, 124, 56];
const arrDouble = arr.map((num) => num * 2);
console.log(arrDouble);
map
很適合用在陣列裡所有的值都需要調整的時候,因為 map
會透過函式所回傳的值組成一個新的陣列。
// 傳統函式寫法
const average = function () {
const nums = Array.from(arguments);
// 使用 reduce 算1~5總和
const total = nums.reduce(function (acc, curr) {
return acc + curr
}, 0);
console.log(total);
// 算平均值
return total / nums.length;
}
console.log(average(1, 2, 3, 4, 5, 10));
average()
此函式會將傳入的參數 ( average(1, 2, 3, 4, 5)
) 全部取出,我們使用 arguments
這個參數。由於 arguments
為類陣列沒有所有陣列的方法,所以 Array.from
使用將它轉為純陣列。箭頭函式寫法
const average = (...num) => num.reduce((acc, curr) => acc + curr, 0) / num.length;
console.log(average(1, 2, 3, 4, 5, 10));
argument
的方式,所以可使用其餘參數來解決無法取出沒有列出的參數問題。// 傳統函式
const person = {
data: {},
// getData 方法可取得遠端資料
getData: function() {
// 將this指向新變數vm
const vm = this;
// 透過ajax取的遠端資料
$.ajax({
url: 'https://randomuser.me/api/',
dataType: 'json',
success: function (data) {
console.log(data);
// vm.data指的是person.data
vm.data = data.results[0];
console.log('person.data', person.data);
}
});
}
}
person.getData();
https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js
調整成箭頭函式
// 箭頭函式寫法
const person = {
data: {},
getData: function() {
// 透過ajax取的遠端資料
$.ajax({
url: 'https://randomuser.me/api/',
dataType: 'json',
success: (data) => {
console.log(data);
// vm.data指的是person.data
this.data = data.results[0];
console.log('person.data', person.data);
}
});
}
}
person.getData();
this
,所以把 success
後方調整成箭頭函式後,裡面的 this
會指向外層作用域 getData
,而基於 getData
是由 person
呼叫所以 this
會指向 person
。success
內原本的 vm
可修改成 this
,const vm = this;
可刪除。