1. 程式人生 > >箭頭函數表達式和聲名式函數表達式的區別以及 Function.prototype的bind, apply,call方法

箭頭函數表達式和聲名式函數表達式的區別以及 Function.prototype的bind, apply,call方法

不知道 -c 兩個 eva 一個 true ice 函數表 prototype

箭頭函數不能用做構造函數

箭頭函數沒有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方法