我理解的this

作者: ziclee | 来源:发表于2018-01-26 16:31 被阅读0次

一直以来,对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元素

相关文章

  • 我理解,我理解

    儿子喜欢打80分,但平时家里凑不够人手。所以每次去外公外婆家都要让外公外婆陪他打牌。 这天去外公外婆家住一晚,儿子...

  • 我对理解的理解

    时下,最值得珍惜的就是信任, 感恩别人对自己的一份信任,理解别人对自己的不理解,这就是我对理解的理解

  • 我的理解!

    说到师德师风,相信人们马上就会想到这样一些词儿:为人师表,爱岗敬业,无私奉献……的确,这说的就是我们人民教室,我们...

  • 我理解的this

    一直以来,对this的指向问题一直没有好好理解,最近得空,赶紧恶补一下。 1、涵义 this是什么? 简单说,关键...

  • 我理解的

    那一天你看见我的作品,并说一句使我感动真心话。你永远我的一生选择的方向标,也是我不舍得把你的岁月故事忘记一干二净。...

  • 我的理解

    我的理解 对事不对人 出轨这件事是一种行为,无好坏之分,主要看三方的品质问题,可以理解为夫妻双方和第三者三方都做出...

  • 我的理解

    所谓正确的育儿理念,仁者见仁智者见智。我的理解是: 家校携手,信任孩子,用爱陪伴,彼此追梦,滋养生命。 →_→...

  • 前端理解的(我理解的)Dockerfile

    什么是Dockerfile Dockerfile 是一个描述文件,是一个用来构建镜像的文本文件,文本内容包含了一条...

  • 我理解我的父母

    上篇文章的时候我想很久,我犹豫到底要不要写出来分享给你们,我写目的不是想表达我的家庭有多不堪,我的成长有多糟糕,我...

  • 我理解

    一直叛逆的我,今天学习过刘润总算知道为什么,我妈老说为你好了,我理解了,她真的为我好,她只不过想让自己的孩子走一条...

网友评论

    本文标题:我理解的this

    本文链接:https://www.haomeiwen.com/subject/mmdwaxtx.html