通常情况下,当我们执行一段代码的时候如执行一个函数,其指向的this
指针都是当前运行的函数执行上下文,也可以理解为一个变量。当为了实现的需求,我们需要对某些运行的代码修改this
指向,这时就可以使用JavaScript
中提供的修改this指向的三种方法:call
、apply
、bind
。
this指向
首先我们来先了解下有关this指向
的基础概念,如下一个this指向的一个示例:
var Car = function() {
console.log(this); // window
console.log(this.Car==window.Car,Car==window.Car); // true true
}
Car(); // 外部调用this指向window对象
this指向
的类型主要分为如下几种:
this
在全局函数中,永远指向window对象this
严格模式中,永远不会指向window
对象,这是的this为undefined
this
出现在构造函数中,指向当前构造函数创建的对象- 当指向函数为某个对象的一个属性,则该函数内部的
this
指向为当前这个对象 Js
中点击事件的回调函数中this
的指向为当前被点击的这个元素- 箭头函数中的
this
指向与其外部父级作用域的this
指向相同
call
call函数为JavaScript中的内置方法,其实现功能就是通过调用一个对象的函数并修改该函数内的this指向,其使用语法格式如下:
call(thisobj,arg1, arg2, ...)
thisobj
:修改后的this值arg1, arg2, ...
:函数接收的函数参数
通过上述的了解,我们通过一个示例来理解如何使用call方法:
let obj1 = {
name: "张三",
age: 24,
user: function (args) {
console.log("姓名:", this.name);
console.log("年龄:", this.age);
console.log("参数", args);
}
}
let obj2 = {
name: "李四",
age: 30,
user: function () {
console.log("姓名:", this.name);
console.log("年龄:", this.age);
console.log("参数", args);
}
}
// 修改this指向
obj1.user.call(obj2, "我是参数"); // 使用call方法改变this指向,将obj1中的user函数内的this指向改为obj2
#执行结果
姓名:李四
年龄:30
参数:我是参数
apply
apply()
方法和call方法实现功能一致,不同的是调用方法传递的参数格式不一致。call使用的是不定长参数,而apply使用的是参数数组。其使用格式如下:
apply(thisobj,[arg1, arg2])
thisobj
:修改后的this值[arg1, arg2]
:函数接收的函数参数
上述示例,我们通过apply实现来看看call的区别:
let obj1 = {
name: "张三",
age: 24,
user: function (args) {
console.log("姓名:", this.name);
console.log("年龄:", this.age);
console.log("参数", args);
}
}
let obj2 = {
name: "李四",
age: 30,
user: function () {
console.log("姓名:", this.name);
console.log("年龄:", this.age);
console.log("参数", args);
}
}
// 修改this指向
obj1.user.apply(obj2, ["我是参数"]); // 使用apply方法改变this指向,将obj1中的user函数内的this指向改为obj2
#执行结果
姓名:李四
年龄:30
参数:我是参数
bind
bind的使用格式和call一样,第一个参数传入的是this指向对象,后面的参数为不定长参数列表,不同的是bind函数可以分多次传参,而call则是一次性传入。导致这种情况的原因是:bind函数指向返回一个函数变量,并不会立即执行,需要再次调用返回的函数变量,而call调用后会自动执行。先简单看下调用格式:
bind(thisobj,arg1,arg2,arg3)
通过如下代码来了解下如何使用bind函数:
let obj1 = {
name: "张三",
age: 24,
user: function (args) {
console.log("姓名:", this.name);
console.log("年龄:", this.age);
console.log("参数", args);
}
}
let obj2 = {
name: "李四",
age: 30,
user: function () {
console.log("姓名:", this.name);
console.log("年龄:", this.age);
console.log("参数", args);
}
}
// 修改this指向
let a = obj1.user.bind(obj2);//使用bind方法改变this指向,将obj1中的user函数内的this指向改为obj2
a('我是参数') // 二次传参,并执行函数