箭头函数跟普通函数this的区别
- 指向不同
普通函数的this指向方法调用时的对象,可以通过call,apply,bind来改变this指向
箭头函数不会创建自己的this,他只会从自己作用域的上一层继承this。
call,aply,bind,不能改变this指向,只能用来传递参数
var obj = {
a: 10,
b: () => {
console.log(this.a) // undefined
console.log(this) // Window
},
c: function () {
console.log(this.a) // 10
console.log(this) // {a:10, b:()=>{},c:f()}
}
}
console.log(obj.b())
console.log(obj.c())
- 箭头函数没有原型
var a = () => { }
console.log('原型', a) // ()=>{}
console.log('原型', a.prototype) // undefined
- 箭头函数不能绑定argument,取而代之的事rest参数...来解决
let A = () => {
console.log(arguments); // arguments is not defined
}
A(1, 2, 3, 4, 5, 8);
let B = (...rest) => {
console.log(rest); // [1, 2, 3, 4, 5, 8]
console.log(Object.prototype.toString.call(rest)) // [object Array]
}
B(1, 2, 3, 4, 5, 8);
这也说明,es6中的rest(...)参数,返回的是一个数组类型,不像arguments返回的是类数组
- 箭头函数是匿名函数,不能作为构造函数,不能new
无法实例化的原因:
没有自己的this,无法调用call,apply来改变this指向。如果非要改变,那就直接该父类的this
没有prototype属性,而new命令执行的时候需要将构造函数的prototype赋值给新的对象的_proto
手写call,apply,bind
// call实现
Function.prototype._call = function (context, ...args) {
const fn = Symbol('fn')
let ctx = context || window
ctx.fn = this
let res = args.length > 0 ? ctx.fn(...args) : ctx.fn()
delete ctx.fn
return res
}
// apply实现
Function.prototype._apply = function (context, args = []) {
const fn = Symbol('fn')
let ctx = context || window
ctx.fn = this
if (!(args && args instanceof Array)) {
throw ('请传入数组')
}
let res = args.length > 0 ? ctx.fn(...args) : ctx.fn()
delete ctx.fn
return res
}
// bind实现
Function.prototype._bind = function (context, ...args) {
let that = this
return function () {
return that._call(context, ...args)
}
}
var name = "1";
var obj = {
name: 2,
prop: {
name: 3,
getName: function (age, s) {
return {
name: this.name,
age: age,
s: s
}
}
}
}
console.log(obj.prop.getName(3, 4)); // 3, 3, 4
console.log(obj.prop.getName.call(obj, 3, 4)); //this是obj 2, 3, 4
console.log('_call实现', obj.prop.getName._call(this, 3, 4)); //this是window 1, 3, 4
console.log('_apply实现', obj.prop.getName._apply(this, [2, 3])); //this是window 1, 2, 3
let bindHandle = obj.prop.getName._bind(this, 2, 3)
console.log('bindHandle()', bindHandle())//this是window 1, 2, 3
类数组转化为数组
let A = function () {
console.log('类数组', arguments); // Arguments(6) [1, 2, 3]
console.log('法一', Array.prototype.slice.call(arguments)); // [1, 2, 3]
console.log('法二', Array.from(arguments)); // [1, 2, 3]
console.log('法三', [...arguments]); // [1, 2, 3]
}
A(1, 2, 3);
行文思考
- bind的实现,其实是利用了闭包,和延迟执行(柯里化)这两个特性。
闭包文章输出地址
柯里化
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!