箭头函数表达式和声名式函数表达式的区别以及 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

 

posted @ 2019-05-13 16:55  被爱浸润的智慧体  阅读(182)  评论(0编辑  收藏  举报