0
点赞
收藏
分享

微信扫一扫

JS--改变this的指向--方法/实例


简介

说明

        本文介绍JavaScript如何改变this的指向。

        ES5中this的指向以及ES6中箭头函数的指向​

方法简介

一共有如下5种方法改变this的指向。


  1. this替换
  2. 箭头函数
  3. call
  4. apply
  5. bind

为什么要改变指向

需求:写一个定时任务,一秒钟之后执行,执行时调用另一个函数。

问:你觉得下方的程序能否执行?

let name = "Hello";
let obj = {
name: "Tony",
func1: function() {
console.log(this.name);
},

func2: function() {
setTimeout(function() {
this.func1()
}, 1000);
}
};
obj.func2();

结果

Uncaught TypeError: this.func1 is not a function

原因

        调用obj.func2,在setTimeout中调用this.func1,但setTimeout里边的函数在1秒钟后是由window对象调用的,所以this指向window,但window中没有func1函数,所以会报错。

法1:this替换

func2函数中,this指向对象obj,把this指向赋值给_this,在setTimeout中使用_this来访问func1。

let name = "Hello";
let obj = {
name: "Tony",

func1: function() {
console.log(this.name); // Tony
},

func2: function() {
let _this = this;
setTimeout(function() {
console.log(_this); // {name: 'Tony', func1: ƒ, func2: ƒ} 即:obj对象
_this.func1()
}, 1000);
}
};
obj.func2();

结果

{name: 'Tony', func1: ƒ, func2: ƒ}
Tony

法2:箭头函数

ES6的新特性:箭头函数。

let name = "Hello";
let obj = {
name: "Tony",

func1: function() {
console.log(this.name); // Tony
},

func2: function() {
setTimeout(() => {
console.log(this); // {name: 'Tony', func1: ƒ, func2: ƒ} 即:obj对象
this.func1()
}, 1000);
}
};
obj.func2();

结果

{name: 'Tony', func1: ƒ, func2: ƒ}
Tony

法3:call

说明

        call执行一个函数:函数名.call(作用域对象),将函数放到特定的作用域对象中执行。下面这个例子中通过call将setTimeout函数的作用域对象从window改成了obj。

用法

    function.call(thisArg, 参数1, 参数2, 参数3...)


        function: 要改变this指向的原函数

        thisArg:  要改变到的this指向的目标对象

示例

let name = "Hello";
let obj = {
name: "Tony",

func1: function() {
console.log(this.name); // Tony
},

func2: function() {
setTimeout(function() {
console.log(this); // {name: 'Tony', func1: ƒ, func2: ƒ} 即:obj对象
this.func1()
}.call(obj), 1000);
}
};
obj.func2();

结果

{name: 'Tony', func1: ƒ, func2: ƒ}
Tony

法4:apply

说明

apply执行一个函数,函数名.apply(作用域对象)。

用法

function.apply(thisArg, [参数1, 参数2, 参数3...])

function: 要改变this指向的原函数

thisArg: 要改变到的this指向的目标对象

如果打印形参,结果并不是一个数组,而是数组里面的值,并且元素与形参一一对应

示例

let name = "Hello";
let obj = {
name: "Tony",

func1: function() {
console.log(this.name); // Tony
},

func2: function() {
setTimeout(function() {
console.log(this); // {name: 'Tony', func1: ƒ, func2: ƒ} 即:obj对象
this.func1()
}.apply(obj), 1000);
}
};
obj.func2();

结果

{name: 'Tony', func1: ƒ, func2: ƒ}
Tony

法5:bind

语法

funtion.bind(thisArg, 参数1, 参数2, 参数3...)

thisArg: 要改变到的this指向的目标对象 该方法并不会调用函数,仅仅改变了this指向。

示例

let name = "Hello";
let obj = {
name: "Tony",

func1: function() {
console.log(this.name); // Tony
},

func2: function() {
setTimeout(function() {
console.log(this); // {name: 'Tony', func1: ƒ, func2: ƒ} 即:obj对象
this.func1()
}.bind(obj), 1000);
}
};
obj.func2();

call,apply,bind的区别

相同点

都可以改变函数内部的this指向

不同点

call

apply

bind

是否调用函数

立即执行函数

立即执行函数


不立即执行函数。

返回新函数,便于稍后调用


传参


可以。

传数组。

一次性传入参数。



可以。

传参数列表。

一次性传入参数。



可以。

可以多次传入参数。



使用场景

继承

经常跟数组有关系。比如借助数学对象实现数组最大值最小值

改变定时器内部的this指向


举报

相关推荐

0 条评论