JavaScript基础(2)— this/call/apply/bind

  1. this
  • this的指向,是在函数被调用的时候确定的,也就是执行上下文被创建的,而不是创建时决定的。
  • 调用位置:函数在代码中被调用的位置,而不是声明的位置。

(1)全局对象中的this

  • this等价于widow对象
// 通过声明绑定到变量对象,但在全局环境中,变量对象就是它自身
var a1 = 10;
console.log(a1);  //10
// 通过this绑定到全局对象
this.a2 = 20;
console.log(a2);  //20
// 仅仅只有赋值操作,标识符会隐式绑定到全局对象
a3 = 30;
console.log(a3);  //30

console.log(this === window)  //true

所以 var === this. === window.

(2)函数中的this

  • this由调用者提供,由调用函数的的调用方式来决定。
  • 如果调用者函数,被一个对象所拥有,那么该函数在调用时,内部的this指向该对象。
  • 如果函数独立调用,那么该函数内部的this,则指向undefined,非严格模式下,当this指向undefined时,它会自动指向全局对象。

例1

var a = 20;
var obj = {
  a: 10,
  c: this.a + 20,
  fn: function () {
    return this.a;  
  }
}

console.log(obj.c);  //40  注:单独的{}对象不会形成新的作用域,所以this.a没有作用域的限制,仍处于全局
console.log(obj.fn());  //10  调用者是fn,被obj所拥有,所以this指向obj对象

例2

var a = 20;
var foo = {
  a: 10,
  getA: function () {
    return this.a;
  }
}
console.log(foo.getA()); // 10  getA是调用者,被对象foo拥有,不是独立调用,所以this指向foo

var test = foo.getA;
console.log(test());  // 20  test为调用者,这时的它是独立调用,所以this指向window(非严格模式)

例3

function foo() {
  console.log(this.a)
}
function active(fn) {
  fn(); // 真实调用者,为独立调用
}
var a = 20;
var obj = {
  a: 10,
  getA: foo
}
active(obj.getA);  //active为调用者,独立调用

(3)使用call/apply指定this

  • 一种可以自行手动设置this指向的机制。
  • 所有的函数都具有这两种方法(非继承而来的方法),除了参数略有不同,其功能完全一样。
  • 第一个参数是undefined或者null,非严格模式下,是指向window。严格模式下,就是指向第一个参数。
  • call的参数是一个列表,将每个参数一个个列出来。
  • apply只接受两个参数,第二个参数是一个数组或类数组,将每个参数放到一个数组中。

例1

function fn(num1, num2) {
  console.log(this.a + num1 + num2);
}
var obj = {
  a: 20
}
//fn并非属于对象obj的方法,但是通过call,我们将fn内部的this绑定为obj,因此就可以使用this.a访问obj的a属性了
fn.call(obj, 100, 10); // 130
fn.apply(obj, [20, 10]); // 50

例2

var name = 'window中';
var doSth = function(){
    console.log(this.name);
}
var student = {
    name: 'student中',
    doSth: doSth,
    other: {
        name: 'other中',
        doSth: doSth,
    }
}
doSth(); // 'window中'  独立调用,this指向全局
student.doSth(); // 'student中'  被对象student所拥有,指向student对象
student.other.doSth(); // 'other中' 被other对象所拥有,指向other对象
student.doSth.call(student); // 'student中'  
student.other.doSth.call(student); // 'student中' 被other所拥有,但是被call改变this指向,指向student对象

注意:通常情况下,大家会做如下处理,把对象中的函数赋值给一个变量,在进行调用,实际上这样又把该函数调用变成普通函数了,所有指向全局(非严格模式下)。

var studentDoSth = student.doSth;
studentDoSth(); // 'window中'

***参考链接:
1、前端基础进阶(七):全方位解读this/
2、面试官问:JS的this指向

(4)bind

  • bind()方法主要是将函数绑定到某个对象上,bind()会创建一个函数,函数体内的this对象的值会被绑定到传入bind()第一个参数的值,例如:fn.bind(obj),实际上可以理解为obj.fn(),这时,fn函数体内的this,自然指向obj。
  • this将永久的被绑定到bind的第一个参数。

例1:

var a = {
	b : function(){
		var func = function(){
			console.log(this.c);
		}
		func();
	},
	c : 'Hello!'
}
a.b(); //undefined
-------//对比上下两个例子,上面的func()属于直接调用,下面的调用者b被对象a拥有,所以this指向有差别
var a = {
	b : function(){
		console.log(this.c);
	},
	c : 'Hello!'
}
a.b(); //Hello

做简要的改造:

var a = {
	b : function(){
		var that = this;  //可以通过赋值的方式将this赋值给that
		var func = function(){
			console.log(that.c);
		}
		func();
	},
	c : 'Hello!'
}
a.b();  //Hello!

通过bind的方式绑定this

var a = {
	b : function(){
		var func = function(){
			console.log(this.c);
		}.bind(this);
		func();
	},
	c : 'Hello!'
}
a.b(); //Hello!
 
var a = {
	b : function(){
		var func = function(){
			console.log(this.c);
		}
		func.bind(this)();
	},
	c : 'Hello!'
}
a.b(); //Hello!

***参考链接:JS中的bind方法

(5)箭头函数中的this

  • 所有的箭头函数都没有自己的this,都指向外层。
  • this指向定义时所在的对象,而不是运行时所在的对象。

箭头函数常用语回调函数中,例如定时器中:

function foo() {  
  setTimeout(()=>{
    console.log(this.a);
  },100)
}
var obj = {
  a: 2
}
foo.call(obj);  //2
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值