call的用法相关文章:改变this指向,call,apply,bind的不同
一、call方法的实现步骤
1.myCall内部将【第一个参数(this将指向的对象)】身上【添加了一个方法】,【添加的方法】就是【调用myCall的方法】。
2.如果传递了多个参数,应该把除了第一个参数以外的参数当作【添加的方法】的参数。
3.然后用这种方式执【添加的方法】:【第一个参数.添加的方法】。并保存他的返回值。
4.执行完【添加的方法】后要删除【添加的方法】。
5.返回执行【添加的方法】后保存的返回值。
二、必备知识点
1.call的作用要有所了解:改变this指向,call,apply,bind的不同
2.普通函数的this指向题:【谁调用只想谁,比如:对象调用方法,方法的this指向对象】,call的实现也是利用了这一点。更多关于this指向看这里:this指向问题
3.实现call我们就要把自己定义的myCall挂到Function的原型prototype上,这样所有的方法就都可以使用了。
4.对象传递是引用传递,即传递的是地址,若改变值,则其他使用该对象的地方也很会对应改变
三、用this将方法绑定到myCall上的原理(结合知识点2和3)
// 知识点第3点,挂到原型上
Function.prototype.myCall = function () {
console.log(this); // 打印一下this,看看方法调用的时候this指向谁。
}
// 定义一个使用myCall的函数。
function test() {}
test.myCall(); // 输出结果:ƒ test() {} 。
// 原因就是知识点2,test调用了myCall,所以myCall的this指向了test。
// 在真是放些call时也是利用了这一点,把this赋给this将指向的对象里的一个属性,实质是把this原本的方法赋值到了对象的属性上,然后用对象调用属性方法执行,这时属性方法内部的this就指向了这个对象,而属性方法本身就是调用call时的那个方法。
四、实现myCall并测试
// 用于方法改变this的对象
const obj = {
name: '张三'
};
// 测试方法,带有返回值。
function sayHello(age, sex) {
console.log(`Hello ${this.name},age:${age},sex:${sex}`);
return {
name: this.name,
age: age,
sex: sex
}
}
// 实现myCall
Function.prototype.myCall = function (obj) {
// 拿到obj,如果obj隐式转换是false,那么取window
const object = obj || window;
object.fun = this; // 上面已经测试过,this指向的是调用myCall方法的函数,这相当于在对象里创建了一个叫fun的函数,函数体是调用myCall方法的函数
// const arg = Array.prototype.slice.apply(arguments, [1]); // 截取arguments参数列表除第一个以外的参数,与下面es6方法效果相同
const [, ...arg] = arguments; // arguments是参数列表,这是es6的解构语法,拿到除第一个参数以外的参数
const result = object.fun(...arg); // 执行通过this绑定的方法,并拿到返回值,因为函数有可能会有返回值,所以需要接收
delete object.fun; // 知识点3,对象是引用传递,我们不能改变传进来的参数,所以我们要从传进来的参数身上把我们通过this绑定的方法删除掉。
return result; // 返回执行函数的结果,如果不返回,会输出undefined。
}
console.log(sayHello.myCall(obj, 18, "男"));
到这里就结束了。后续会有bind和apply方法。
如果对你有帮助可以👍+关注哦~~我们一起学前端