最近又进行了基础知识的重新学习,然后进行了call,apply,bind的this指向、参数类型以及代码的手写,然后整理了下。
this指向
// this指向
const phper = {
name: 'php',
getName: function(){
console.log(this.name+'is the best language in the world');
}
};
const webfansDoLi = {
name: 'javascript',
};
phper.getName();
phper.getName.call(webfansDoLi);
phper.getName.apply(webfansDoLi)
phper.getName.bind(webfansDoLi)()
//打印结果:javascript is the best language in the world
//打印结果:javascript is the best language in the world
//打印结果:javascript is the best language in the world
结论:call、apply、bind的this都是指向他们的第一个参数。
参数类型
// 参数注入(异同比较)
const developer = {
getSkills: function(...args){
console.log(...args);
},
};
const webfansDoLi = {
getSkills: ['html'],
}
developer.getSkills.call(webfansDoLi,'es6','计算机基础');
developer.getSkills.apply(webfansDoLi,['hBuilder','微信小程序']);
developer.getSkills.bind(webfansDoLi,'vue','react')()
//打印结果:es6 计算机基础
//打印结果:hBuilder 微信小程序
//打印结果:vue react
结论:call和bind的第二个参数是开始都是实参参与,而apply则是第二个参数是参数数组(速记参数差异:apply参数是array,都是a开头)。
手写绑定
所有的绑定都是绑定在Function函数的prototype属性上的。
手写call
// 简易模拟实现--call
Function.prototype.call = function(context){
console.log(1)
//重定义this
const DoLi = context || window;
//模拟档期那的对象的this指向
DoLi.func = this;
//获取参数
const args = Array.from(arguments).slice(1);
//绑定参数
const res = arguments.length>1?DoLi.func(...args):DoLi.func();
//清除定义的this
delete DoLi.func;
//返回结果
return res;
}
let a = {
name: 'I am a',
sayName: function(...out){
console.log(this.name+(out?out:""));
}
};
let b = {
name: 'I am b'
};
a.sayName.call(b,'我是额外参数','参数2')
//输出结果:1
//输出结果:I am b我是额外参数,参数2
难点:this指向和参数列表截取需要注意
手写apply
// 简易模拟实现--apply
Function.prototype.apply = function(context){
console.log(1)
//重定义this
const DoLi = context || window;
//模拟档期那的对象的this指向
DoLi.func = this;
//获取参数
const args = Array.from(arguments).slice(1,);
//绑定参数
const res = arguments.length>1?DoLi.func(args):DoLi.func();
//清除定义的this
delete DoLi.func;
//返回结果
return res;
}
let a = {
name: 'I am a',
sayName: function(out){
console.log(this.name+(out?out:""));
}
};
let b = {
name: 'I am b'
};
a.sayName.apply(b,['我是额外参数','参数2'])
//输出结果:1
//输出结果:I am b我是额外参数,参数2
难点:能写出上面的call的话,这个只需要注意下第二个参数是数组就可以
手写bind
// 简易模拟实现--bind
Function.prototype.bind = function(context){
console.log(1)
//深拷贝,防止污染
const DoLi = JSON.parse(JSON.stringify(context)) || window;
//模拟档期那的对象的this指向
DoLi.func = this;
//获取参数
const args = Array.from(arguments).slice(1,);
// 返回一个绑定的函数,等待调用
return function() {
//返回结果
return args.length>0?DoLi.func(...args):DoLi.func();
}
}
let a = {
name: 'I am a',
sayName: function(out){
console.log(this.name+(out?out:""));
}
};
let b = {
name: 'I am b'
};
a.sayName.bind(b,['我是额外参数','参数2'])()
//输出结果:1
//输出结果:I am b我是额外参数,参数2
难点:手写bind函数需要返回一个绑定函数,而不是一个结果。
好的,完成。
月如钩,无言独上西楼 ——煜李
本文使用 mdnice 排版