【深入学习JS】04_this

本文详细介绍了JavaScript中的this关键字及其四种绑定规则:默认绑定、隐式绑定、显示绑定和new绑定,以及箭头函数如何改变this的行为。通过示例展示了在不同场景下this的指向,并强调了在复杂代码中使用this简化上下文传递的重要性。同时,文章总结了this绑定的优先级,帮助读者更好地理解和应用this。
摘要由CSDN通过智能技术生成

为什么要使用this

一句话就是,使用this在某些场合下面可以简化代码。又到了举例子的时候了,在不使用this的时候,需要传入上下文对象:

function identify(context){
    return context.name.toUpperCase();
}

function speak(context){
    var greeting = `Hello, I'm ${identify(context)}`;
    console.log(greeting);
}

var me = { name: 'Armouy' };
var you = { name: 'sugarMei'};

speak(me);
speak(you);

如果使用了this:

function identify(){
    return this.name.toUpperCase();
}

function speak(){
    var greeting = `Hello, I'm ${identify()}`;
    console.log(greeting);
}

var me = { name: 'Armouy' };
var you = { name: 'sugarMei'};

speak.call(me);
speak.call(you);

当你的代码很复杂的时候,显示地传递上下文对象会很混乱,借助this就会方便很多。但是this的指向问题很容易让人产生混淆。

this的绑定规则

记住一句话,this实际上是在函数调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。这句话很好理解,谁调用了它,它就指向谁。this的绑定规则一共有4种:

默认绑定

function foo(){
    console.log(this.bar);
}
var bar = "bar";
foo();             // bar

foo这种在调用方法,就是默认绑定。在非严格模式下,this指向的是全局作用域;在严格模式下,指向的是undefined

隐式绑定

function foo(){
    console.log(this.bar);
}

var bar = "bar";
var obj = {
    bar: 'bar1',
    foo: foo
}

obj.foo();          // bar1

obj.foo()这种是隐式绑定,foo成为了obj.foo的方法,此时obj调用了这个方法,this就指向了obj;所以this.bar就是obj.bar

显示绑定

function foo(){
    console.log(this.bar);
}

var bar = "bar";
var obj = {
    bar: 'bar1'
}

foo.call(obj);      // bar1

在这里如果通过call、apply或者bind将调用的函数中的this显示的绑定到了obj上,所以this指向的是obj。打印的结果就是bar1了。

new 绑定

function Foo(a){
    this.a = a;
}
var foo = new Foo('a');
console.log(foo.a);       // a

new调用函数,或者说发生构造函数调用时,会自动执行以下操作:

  • 创建一个一个全新的对象:var foo = {}
  • 把这个对象链接到原型对象上foo.__proto__ = Foo.prototype
  • 这个新对象会绑定到函数调用的thisFoo.call(foo, a)
  • 返回对象。如果函数没有返回其他对象,那么new操作会自动返回这个新对象。

箭头函数

箭头函数不适用以上四种绑定规则,它是根据外层(函数或者全局)作用域来决定this的。

对比这两个栗子的输出:

function Person(){
  this.age = 0;
  setTimeout(function () {
    console.log(this.age);     // 输出undefined
  }, 1000);
}
var p = new Person();
function Person(){
  this.age = 10;
  setTimeout(()=> {
    console.log(this.age);     // 输出10
  }, 1000);
}
var p = new Person();

总结

  • 绑定的优先级: 箭头函数绑定 > new 绑定 > 显示绑定 > 隐式绑定 > 默认绑定
  • 可以根据以下规则来判断是哪一种绑定:
    • 函数是否在new中调用,是的话,this绑定的是新创建的对象;
    • 函数是否是通过call、bind或者apply进行的显示绑定,是的话,this执行的就是绑定的那个对象;
    • 函数是否在某个上下文对象中被调用,这就是隐形调用,this绑定的是那个上下文,例如:let obj = new Foo();
    • 如果都不是那就是默认绑定,this指向的是全局。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值