作者:长安曹公子
連接:https://juejin.im/post/6844903805960585224
來源:掘金
比一般定義函數還簡潔
// 箭頭
let foo = (bar, baz) => {
console.log(bar);
return bar
}
// 一般
let foo = function(bar, baz) {
console.log(bar)
return bar
}
一些更簡潔的寫法
// 變量只有一個可以不用括號
let foo = bar => {
return bar
}
// 如果只有一行回傳值可以不用中括號(跟上面意思一樣)
let foo = bar => bar
// 如果返回的是一個對象外面要括號(很少這樣寫)
let foo = bar => ({id: bar, name: 'Mike'})
// 等價於這樣
let foo = bar => {
return {
id: bar,
name: 'Mike'
}
}
// 如果只有一行代碼然後要執行函數可以加void
let foo = () => void bar();
箭頭函數只會繼承上一層this,意思是他會去找定義時的外層執行環境的this,因此箭頭函數的this的this在定義時就被決定,不會再有更改
var foo = 'global'
let fun1 = function () {
setTimeout(() => {
console.log(this.foo) // 指向fun1函數體的this(看下下行)
}, 1000);
// 比方說這裡
console.log(this)
}
let fun2 = function () {
setTimeout(function () {
console.log(this.foo);
}, 1000);
}
fun1.call({foo: 'obj'})
fun2.call({foo: 'obj'})
解析:
我們透過call把對象綁定到fun1以及fun2的tihs
fun1裡面的setTimeout是利用箭頭函數定義,所以會指向fun1的this,因此打印出來綁定對象的foo即是obj
fun2裡面的setTimeout是利用普通函數定義,所以會指向最後調用的對象,雖然我們把對象綁定到fun2上,可是最後執行的其實是window(因為setTimeout)
喔看起來已經相當清楚了呢~我們繼續來看下去
var id = 'global'
obj = {
id: 'foo',
test: () => {
console.log(this.id)
}
}
obj.test() // global
解析:
很明顯,假設是一般函數打印出來會是global,因為this會指向最後調用的對象
但這題會打印出函數定義時候會指向定義時的環境this,所以會指向window
這裡要注意,定義對象的大括號
{}
是無法形成一個單獨的執行環境的,它依舊是處於全局執行環境中!!
這一題證明了會指向外層的this
function foo() {
let _this = this // 透過變量儲存this
let bar = () => {
console.log(this == _this)
}
bar()
}
foo()
因為在定義時箭頭函數的this已經被定義,因此假如我們想要改變箭頭函數的this其實應該要改變外層的this指向
證明不能直接改變
let foo = function () {
console.log(this);
}
let baz = () => {
console.log(this); // 肯定指向window對象
}
foo.call({bar: 'bar'})
baz.call({bar: 'bar'})
透過改變外層,其實就是 (不會創造this的例子一)
var id = 'global'
let bar = function () {
let obj = {
id: 'foo',
test: () => {
console.log(this.id);
}
}
return obj.test
}
let bazCall = bar.call({id: 'bazCall'})
bazCall()
解析:
其實不難啦
就是要改變bar的this,因為test函數的this永遠指向bar的this
// 綁定對象給bar
let bazCall = bar.call({id: 'bazCall'})
bazCall()
let Foo = (bar, age) => {
this.bar = bar;
this.age = age;
};
let instance = new Foo ('Mike', 15);
let foo = () => {
};
console.log(foo.prototype);
一般函數會顯示所有參數
let foo = function (bar1, bar2) {
console.log(bar1);
console.log(bar2);
console.log(arguments);
}
foo(123, 456)
箭頭函數:
let foo = (bar) => {
console.log(bar);
// 報錯,因為window沒有arguments對象
console.log(arguments);
}
foo(123)
這題簡單來說還是證明箭頭函數會繼承外圍環境的this
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);
最關鍵的代碼是這裡
// let argOut = arguments;
let fun = () => {
// 這裡的arguments其實是繼承自外圍
// 也就是 let argOut = arguments 的 arguments
let argIn = arguments;
console.log(argIn);
console.log(argOut === argIn);
};