js中的this指向问题,call,apply,bind

1.this的最终指向实质上是那个调用它的对象。

1、在对象方法中, this 指向调用它所在方法的对象。
(如果函数调用前存在多个对象,this指向距离调用自己最近的对象)
2、单独使用 this,它指向全局(Global)对象。(window)
3、函数使用中,this 指向函数的所属者。(调用时的事件对象)
4、严格模式下函数是没有绑定到 this 上,这时候 this 是 undefined。
5、在 HTML 事件句柄中,this 指向了接收事件的 HTML 元素。
6、apply 和 call 允许切换函数执行的上下文环境(context),即 this 绑定的对象,可以将 this 引用到任何对象。

2.显式绑定(改变this指向)

call / apply

Function.call(obj/this,args1,args2,args3...)
obj:这个对象,将替代Function里面的this
从第二个参数开始,是一个参数列表

 Function.apply(obj/this,[args1,args2,args3,...]) apply方法接收两个参数
obj:这个对象,将替代Function里面的this
args: apply中第二个参数是一个类数组,他可以作为参数传给Function

Function.bind(obj/this,args1,args2,args3...)()
obj:这个对象,将替代Function里面的this
从第二个参数开始,bind 除了返回是函数以外,后续的参数可以作为函数的参数传入到函数中,
bind()方法和call apply 相似,也可以改变this的指向。


注意:
如果在使用call之类的方法改变this指向时,指向参数提供的是null或者undefined,那么 this 将指向全局对象

三者区别
a.call、apply与bind都用于改变this绑定,但call、apply在改变this指向的同时还会执行函数,而bind在改变
this后是返回一个全新的boundFcuntion绑定函数,这也是为什么上方例子中bind后还加了一对括号 ()的原因。

b.bind属于硬绑定,返回的 boundFunction 的 this 指向无法再次通过bind、apply或 call 修改;
call与apply的绑定只适用当前调用,调用完就没了,下次要用还得再次绑。

c.call与apply功能完全相同,唯一不同的是call方法传递函数调用形参是以散列形式,而apply方法的形参是
一个数组。在传参的情况下,call的性能要高于apply,因为apply在执行时还要多一步解析数组。

当我们调用一个函数时,我们习惯称之为函数调用,函数处于一个被动的状态;而call与apply让函数从被动变主动,函数能主动选择自己的上下文,所以这种写法我们又称之为函数应用

call,apply方法除了可以改变this指向外,还可以用于传递参数,因为没有对象去调用Math的这个方法,所以直接传递null过去:ex:

//Math方法中
arrH=[...];
var minH = Math.min.apply(null, arrH)
var obj = {
		abc: '伍天锡'
	};
	var abc = '伍云召';

	function wu() {
		console.log(this.abc);
	}
	wu.call(obj);//伍天锡
	wu.apply(obj);//伍天锡
	wu.bind(obj)();//伍天锡
	

3.隐式丢失

原理:将函数调用作为参数传递或者作为变量的赋值

//参数传递
var name = '行星飞行';
let obj = {
    name: '听风是风',
    fn: function () {
        console.log(this.name);
    }
};

function fn1(param) {
    param();
};
fn1(obj.fn);//行星飞行

上边的行星飞行例子类似于

var obj = {
  foo: function () { console.log(this.bar) },
  bar: 1
};

var foo = obj.foo;
var bar = 2;

obj.foo() // 1
foo() // 2

//虽然obj.foo和foo指向同一个函数,但是执行结果并不一样
//这种差异的原因,就在于函数体内部使用了this关键字。很多教科书会告诉你,
//this指的是函数运行时所在的环境。对于obj.foo()来说,foo运行在obj环境,
//所以this指向obj;对于foo()来说,foo运行在全局环境,所以this指向全局环境。
//所以,两者的运行结果不一样
//隐式丢失的问题是变量赋值,其实本质上与传参相同
var name = '行星飞行';
let obj = {
    name: '听风是风',
    fn: function () {
        console.log(this.name);
    }
};
let fn1 = obj.fn;
fn1(); //行星飞行

4.作用域链与原型链的区别:

当访问一个变量时,解释器会先在当前作用域查找标识符,如果没有找到就去父作用域找,作用域链顶端是全局对象window,如果window都没有这个变量则报错。

当在对象上访问某属性时,首选i会查找当前对象,如果没有就顺着原型链往上找,原型链顶端是null,如果全程都没找到则返一个undefined,而不是报错。

js 五种绑定彻底弄懂this,默认绑定、隐式绑定、显式绑定、new绑定、箭头函数绑定详解

this的原理、函数的不同调用方式this取值、以及不同环境下this的取值、函数四种调用方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值