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