我理解的this

一直以来,对this的指向问题一直没有好好理解,最近得空,赶紧恶补一下。

1、涵义

this是什么?

简单说,关键字“this”指向当前代码运行时的对象(当前运行时调用该属性或方法的对象)

this是在函数调用过程中设置的

例子:

function fn() {
    return this.name;
}

let a = {
    name: '小明',
    who: fn
}

let b = a.who;
console.log(a.who());  //this指向a,当前who方法是被a调用
console.log(b()); //this指向window,当前b处于全局环境下,this.b === window.b,所以this指向window

2、this使用环境

全局上下文

在全局上下文环境中,this指向window对象

// 在浏览器中, window 对象同时也是全局对象:
console.log(this === window); // true
let a = 1;
console.log(window.a); //1
this.b = 2;
console.log(window.b); //2
console.log(b); //2

函数上下文

在函数内部,this的值取决于函数被调用的方式。

例子:

function fn() {
    return this.name;
}

let a = {
    name: '小明',
    who: fn
}

let b = {
    name: '小红',
    who: fn,
    c: {
        d: fn
    }
}


console.log(a.who()); //this指向a
console.log(b.who()); //this指向b
console.log(fn()); //this指向window
console.log(b.c.d()); //this指向b.c,为什么不是指向b呢?那是因为this总是指向直接调用它的最近的对象,this只会向上继承最近的一层,不会继承更上面的层;
let h = b.c.d;
h(); //此时this指向window,因为h处于全局对象中

再看一个例子:

let a = {
    b () {
        console.log(this);
        let c = function () {
            console.log(this);
        }();
    }
}
a.b();
这两个this分别指向什么呢?
//第一个this指向a
//第二个this指向window

为什么会这样呢?
就如开头所说的:在函数内部,this的值取决于函数被调用的方式。

上面例子的函数可以看成如下的变体:

let d = function () {
        console.log(this);
    }
let a = {
    b () {
        console.log(this);
        let c = d();//此时,d相当于是被window调用,所以this此时指向window
    }
}
a.b();

那如果我们还是要坚持第一种写法,那可以对this事先赋予一个变量来保存

let a = {
    b () {
        console.log(this);
        let self = this;
        let c = function () {
            console.log(self);
        }();
    }
}
a.b(); //这样this的值就不会被改变
箭头函数下的this
let a = {
    b () {
        console.log(this);
        let c = () => {
            console.log(this);
        };
        return c;
    }
}
a.b(); // 第一个this指向a
a.b()(); // 两个this都指向a
//两个this都绑定到a,这与非箭头函数的绑定结果完成不一样。
//这是因为当使用箭头函数时,this自动绑定到执行上下文的外层函数上
let f = a.b;
f()(); //此时this指向window,因为this是在执行的时候设置。这时候的f是被window调用,所以this指向window;
let f = a.b(); //此时,this指向a。a.b函数已经被调用,所以this此时已经绑定到a上;
f(); //此时的this绑定到哪里呢?没错,还是在a上,这是因为箭头函数中this的值已经被绑定到外层函数上。

this的绑定方法:call、apply、bind

使用call,或者apply方法可以指定this在执行上下文的指向

call与apply的作用相同,它们的区别在于接受参数的方式不一样。call()接受的参数以列表的形式传参,而apply接受的参数以数组的方式传参

例子:call、apply方法
function sum(b) {
    return this.a + b;
}
let sum1 = {a: 1};
sum.call(sum1, 2); //3 this绑定到sum1
sum.apply(sum1, [2]); //3 this绑定到sum1
例子:bind方法

ES6新增了绑定this的bind()方法,调动fn.bind(obj)方法,会创建一个与fn具有相同函数体和作用域的函数, 同时this将永久地被绑定到指定的obj对象上。

function fn() {
    return this.a;
}
let obj = {
    a: 'binded'
}
let bind1 = fn.bind(obj);
console.log(bind1()); //binded
let bind2 = bind1.bind({a: 'binded2'});
console.log(bind2); //binded

下面两种环境中的this,就是我们经常使用的,略过啦

构造函数中的this

构造函数中的this指向new出来的对象(构造的新对象)

事件处理函数中的this

当函数被用作事件处理函数时,this指向当前触发的DOM对象

例子:

<button onclick="alert(this.tagName)">
  Show this
</button>
// this指向当前target:button元素
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. this之谜 在JavaScript中,this是当前执行函数的上下文。因为JavaScript有4种不同的...
    百里少龙阅读 4,617评论 0 3
  • 函数和对象 1、函数 1.1 函数概述 函数对于任何一门语言来说都是核心的概念。通过函数可以封装任意多条语句,而且...
    道无虚阅读 10,102评论 0 5
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 8,452评论 0 4
  • 安楠恍惚间听见一个声音:“七橙,你先回去吧,告诉父皇,我一个月以后,我自己回去。” 七橙有些顾虑:“这……?...
    妖精芥末油阅读 2,600评论 0 0
  • 沉睡的太阳,背负着启明的希望,在我醒来的这片黑色大地上,穿过高山雨林,终没有将荣耀的光芒洒落在支离破碎的身上,只留...
    点燃回忆阅读 2,915评论 1 0