谈一谈你对this指针的理解

作者: 全栈弄潮儿 | 来源:发表于2019-08-27 09:53 被阅读0次

    为什么要用this

    this提供了一种更优雅的方法来隐式传递一个对象的引用,因此可以将API设计得更加简洁并且易于复用。

    什么是 this

    this 就是一个指针,指向我们调用函数的对象。

    this的值由什么决定

    this的值并不是由函数定义放在哪个对象里面决定,而是函数执行时由谁来唤起决定。

    什么是执行上下文

    执行上下文 是语言规范中的一个概念,用通俗的话讲,大致等同于函数的执行“环境”。具体的有:变量作用域(和 作用域链条,闭包里面来自外部作用域的变量),函数参数,以及 this 对象的值。

    现在起,我们专注于查明 this 关键词到底指向哪。因此,我们现在要思考的就一个问题:

    • 是什么调用函数?是哪个对象调用了函数?

    为了理解这个关键概念,我们来测一下下面的代码。

    let person = {
        name: "Jay",
        greet: function() {
            console.log("hello, " + this.name);
        }
    };
    person.greet();
    

    谁调用了 greet 函数?是 person 这个对象对吧?在 greet() 调用的左边是一个 person 对象,那么 this 关键词就指向 person,this.name 就等于 "Jay"。现在,还是用上面的例子,我加点料:

    let greet = person.greet; // 将函数引用存起来;
    greet(); // 调用函数
    

    你觉得在这种情况下控制台会输出什么?“Jay”?undefined?还是别的?

    正确答案是 undefined。这说明this 的值并不是由函数定义放在哪个对象里面决定,而是函数执行时由谁来唤起决定。

    思考题

    找出 this 的指向

    let name = "Jay Global";
    let person = {
        name: 'Jay Person',
        details: {
            name: 'Jay Details',
            print: function() {
                return this.name;
            }
        },
        print: function() {
            return this.name;
        }
    };
    console.log(person.details.print());  // ?
    console.log(person.print());          // ?
    let name1 = person.print;
    let name2 = person.details;
    console.log(name1()); // ?
    console.log(name2.print()) // ?
    

    词法作用域

    词法作用域也就是在词法阶段定义的作用域,也就是说词法作用域在代码书写时就已经确定了。箭头函数就是遵循词法作用域。

    this 和 箭头函数

    在 ES6 里面,不管你喜欢与否,箭头函数被引入了进来。对于那些还没用惯箭头函数或者新学 JavaScript 的人来说,当箭头函数和 this 关键词混合使用时会发生什么,这个点可能会给你带来小小的困惑和蛋蛋的忧伤。

    当涉及到 this 关键词,箭头函数 和 普通函数 主要的不同是什么?

    箭头函数按词法作用域来绑定它的上下文,所以 this 实际上会引用到原来的上下文。

    思考题

    找出this指向

    let object = {
        data: [1,2,3],
        dataDouble: [1,2,3],
        double: function() {
            console.log("this inside of outerFn double()");
            console.log(this);
            return this.data.map(function(item) {
                console.log(this);      // 这里的 this 是什么??
                return item * 2;
            });
        },
        doubleArrow: function() {
            console.log("this inside of outerFn doubleArrow()");
            console.log(this);
            return this.dataDouble.map(item => {
                console.log(this);      // 这里的 this 是什么??
                return item * 2;
            });
        }
    };
    object.double();
    object.doubleArrow();
    

    经典前端面试题每日更新,欢迎参与讨论,地址:https://github.com/daily-interview/fe-interview


    更多angular1/2/4/5、ionic1/2/3、react、vue、微信小程序、nodejs等技术文章、视频教程和开源项目,请关注微信公众号——全栈弄潮儿

    image

    相关文章

      网友评论

        本文标题:谈一谈你对this指针的理解

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