【JS】 函数的 this 指向

指向问题

  • 哪个对象调用函数,函数里面的this指向哪个对象。
  • 严格模式下:在全局环境中,this指向的是undefined
  • 非严格模式下:在全局环境中,this指向的是window
var name = 22
var a = {
	name: 11,
	say: function(){
		console.log(this.name)
	}
}
var fun = a.say
fun()	// 相当于fun.call(window),结果22
a.say()	// 相当于a.say.call(a),结果11

var b = {
	name: 33,
	say: function(fun){
		fun()	// 22
	}
}
b.say(a.say) // 相当于fun(),结果22
b.say = a.say
b.say()	// 相当于b.say.call(b),结果33

在函数中直接使用(window)

  1. 全局定义的函数直接调用,this => window
function fn(){
	console.log(this);
	// 此时 this 指向 window
}
fn();
// 相当于 window.fn()
  1. 定时器的处理函数,this => window
setTimeout(function(){
	console.log(this);	
},0)
// 此时定时器处理函数里面的this 指向 window
  1. 自调用函数,this => window
(function () {
  console.log(this)
})()
// 此时 this 指向 window

作为对象方法调用(调用者)

  1. 对象内部的函数调用,this => 调用者
var obj = {
	fn:function(){
		console.log(this);
	}
}
obj.fn();
// 此时 this 指向 obj
  1. 事件处理函数,this => 调用者
div.onclick = function(){
	console.log(this);
}
//当你点击 div 的时候,this指向 div

改变指向

刚才我们说过的都是函数的基本调用方式里面的 this 指向,我们还有三个方法可以忽略函数本身的 this 指向转而指向别的地方。这三个方法就是 call / apply / bind,是强行改变 this 指向的方法。

  • call/apply/bind附加在函数调用后面使用,可以忽略函数本身的 this 指向
  • call和apply使用时会立即自动调用函数,bind使用时会创建一个函数,但是需要另外去手动调用
  • func.apply(this, arguments) 等价于 func.call(this, ...arguments)

单个参数 call

  • 语法:fn.call(fn 函数体内 this 的指向哪里,arg1, arg2, ...);
  • 作用:调用被绑定的函数fn,指定它的 this 指向并传参
  • 参数:
    • 第一个参数:是 this 指向
    • 其余的参数:需要传入的值,可以是多个,用逗号隔开

  • 使用 call 方法指定 this
var name = 'Rose';
var obj = {name:'Jack'};
function fn(){
	console.log(this.name);
}
fn();	// Rose
fn.call();	// Rose
fn.call(obj);  // jack
  • 使用 call 方法指定 this 并传参
var obj = {name:'jack'};
function fn(a,b){
	console.log(this,a,b);
}
fn(1,2);	// window 1 2
fn.call(obj,1,2);	// obj 1 2
fn(1,3);	// window 1 3

创建函数 bind

  • 语法:fn.bind(fn 函数体内 this 的指向, arg1, arg2, ...);
  • 作用:创建一个新的绑定函数,指定它的 this 指向并传参,必须调用它才会被执行
  • 参数:
    • 第一个参数:this 指向的对象
    • 其余的参数:需要传入的值,可以是多个,用逗号隔开

  • 使用 bind 方法指定 this
var name = "rose"
var obj = {name:'jack'};
function fun(a,b){
	console.log(this,this.name);
}
var funName = fun.bind(obj)
funName()	// obj "jack"
  • 使用 call 方法指定 this 并传参
function fn(a,b){
	console.log(this,a,b);
}
fn(1,2);	// window 1 2
fn.bind(obj,1,2);	// 未调用不执行
fn.bind(obj,1,3)()	// obj 1 3
var newFn = fn.bind(obj,3,4);
newFn();	// obj 3 4
newFn(5,6);	// obj 3 4

数组参数 apply

  • apply方法接受的是一个包含多个参数的数组
  • 语法:fn.apply(fn 函数体内 this 的指向哪里,[arg1, arg2, ...]);
  • 作用:调用被绑定的函数fn,指定它的 this 指向并传参
  • 参数:
    • 第一个参数:this 指向的对象
    • 第二个参数:一个包含多个参数的数组

  • 使用 apply 方法指定 this
var name = 'Rose';
var obj = {name:'Jack'};
function fn(){
	console.log(this.name);
}
fn();	// Rose
fn.apply();	// Rose
fn.apply(obj);  // jack
  • 使用 apply 方法指定 this 并传参
var obj = {name:'jack'};
function fn(a,b){
	console.log(this,a,b);
}
fn([1,2]);	// window 1 2
fn.apply(obj,[1,2]);	// obj 1 2
fn([1,3]);	// window 1 3
  • 15
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一颗不甘坠落的流星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值