箭頭函數表達式和聲名式函數表達式的區別以及 Function.prototype的bind, apply,call方法
箭頭函數不能用做構造函數
箭頭函數沒有arguments參數
箭頭函數沒有自己的this,是從作用域鏈上取this,是與箭頭函數定義的位置有關的,與執行時誰調用無關,所以用call,apply,bind去調用箭頭函數時,第一個參數會被忽略。非箭頭函數是在函數調用時,在當前執行上下文裏動態的取this。
Function.prototype的bind, apply,call方法:
apply,call和bind都為改變this的指向,利用這一點可以用它們來實現繼承
function objFun() { this.age = 18; console.log(this) }; const obj = {name:‘example‘}; const bindFun= objFun.bind(obj); bindFun();//{age:18, name: ‘examle‘}
apply用於不知道參數具體個數的情況下,參數的個數是固定值時,用call.
bind有別於以上兩者的是,它不會立即的執行,它只是一個綁定,即提前為該函數指定this指向和預設參數。
用bind來實現偏函數, 在 bind時可以預設初始參數。在後繼調用時,會將預設參數加到參數列表前面,再執行目的函數。
function objFun(name, age, address) { this.name = name; this.age = age; this.address = address; console.log(this) }; const obj = {name:‘example‘}; const bindFun= objFun.bind(obj, obj.name); bindFun(18, ‘China‘); // 第一個參數name被預設為example,而且不可改變。即後繼執行多少次bindFun,name值都為exapmle
bind可以配合setTimeout使用,可以使this指向類實例。 使用window.setTimeout時會將this指向window。當需要this指向實例對象時,需要將this做為bind的參數來用於setTimeout內的回調函數上。
function F() { this.name = ‘example‘; } F.prototype.show = function() { setTimeout( console.log.bind(console, this.name), 1000);
或者 setTimeout( Function.prototype.bind.call(console.log, console, this.name), 1000);
} const f = new F(); f.show();
setTimeout的第一個參數為回調函數,即函數的聲名。如果不是函數,而是一行代碼的話,比如 console.log(1), 會報和eval()一樣的安全風險.
bind還可用於apply和call方法,來實現快捷調用
Array.prototype.slice.apply([1,2,3]) <=> const slice = Function.prototype.apply.bind(Array.prototype.slice); slice([1,2,3]) // slice的參數不固定,所有bind apply方法
const map = Function.prototype.call.bind(Array.prototype.map, [1,2,3]); //數據的map方法就兩個參數,所以此處bind call方法 map(i => console.log(i)) map(i=> i * 2) map(i => `我是${i}`)
Function.protoType.call.bind/ Function.protoType.bind.call/Function.protoType.apply.call/Function.protoType.apply.bind以及ES6的Reflect.apply
1 Function.protoType.call.bind
綁定call這個函數
var unboundSlice = Array.prototype.slice; var slice = Function.prototype.call.bind(unboundSlice); function list() { return slice(arguments); } var list1 = list(1, 2, 3); // [1, 2, 3]
2 Function.protoType.bind.call
立即執行bind函數
setTimeout( Function.prototype.bind.call(console.log, console, this.name), 1000);
3 Function.protoType.apply.call
立即執行apply函數
Function.prototype.apply.call(console.log, console, [1,2,3])
4 Function.protoType.apply.bind
var log = Function.prototype.apply.bind(console.log, console); log([1 ,2 ,3]) // 1 2 3
5 Reflect.apply
等價於Function.prototype.apply.call
Reflect.apply(console.log, console, [1, 2, 3]) // 1 2 3
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
http://www.ituring.com.cn/article/128553
箭頭函數表達式和聲名式函數表達式的區別以及 Function.prototype的bind, apply,call方法