zoukankan      html  css  js  c++  java
  • 7个关于JS中的this关键字面试题

    在JS中,this 指的是函数调用的上下文。

    但其实,它的行为很复杂,这也是在面试中,常常会被问到的问题。

    下面来说说7个有趣的面试题。

    一、可变和属性

    先来看一段代码:

    const object = {
            message: 'Hello, World!',
    
            getMessage() {
                const message = 'Hello, Earth!';
                return this.message;
            }
        };
    
        console.log(object.getMessage()); // 打印输出的是?

    答案是“Hello,World”。

    因为object.getMessage()是方法调用,所以this指向的object。

    二、回答猫的名字

    function Pet(name) {
            this.name = name;
    
            this.getName = () => this.name;
        }
    
        const cat = new Pet('Fluffy');
    
        console.log(cat.getName()); // 输出的是?
    
        const { getName } = cat;
        console.log(getName());     // 输出的是?

    两个输出都是:“Fluffy”。

    当一个函数被调用作为构造函数,该构造函数内等于所构造的对象。

    this.name = name相当于构造函数中的表达式在构造name对象上创建属性。

    而this.getName = () => this.name在构造函数上创建一个方法,而且它是一个箭头函数,所以this指向还是构造函数Pet。

    在调用cat.getName()和getName()都是返回的this.name。

    三、延时执行

    const object = {
            message: 'Hello, World!',
    
            logMessage() {
                console.log(this.message); // 输出的是?
            }
        };
    
        setTimeout(object.logMessage, 1000);

    在延迟1秒后,打印输出的是 undefined 。

    尽管setTimeout()函数将object.logMessage()用作回调,但它仍是作为常规函数,而不是作为函数调用。

    在常规函数调用中,this是作为全局对象的,可以说是指向window。

    那没有声明全局message参数,所以也就说明为什么输出的是undefined。

    四、功能完善

    const object = {
            message: 'Hello, World!'
        };
    
        function logMessage() {
            console.log(this.message); // "Hello, World!"
        }
    
        // 怎么实现上述结果

    实现的方法有三种:

    const object = {
      message: 'Hello, World!'
    };
    
    function logMessage() {
      console.log(this.message); // logs 'Hello, World!'
    }
    
    // 使用call()方法
    logMessage.call(object);
    
    // 使用apply()方法
    logMessage.apply(object);
    
    // 创建约束函数
    const boundLogMessage = logMessage.bind(object);
    boundLogMessage();

    五、问候和告别

    const object = {
      who: 'World',
    
      greet() {
        return `Hello, ${this.who}!`;
      },
    
      farewell: () => {
        return `Goodbye, ${this.who}!`;
      }
    };
    
    console.log(object.greet());    // 输出的是?
    console.log(object.farewell()); // 输出的是?

    输出的是“Hello,World”和“Goodbye,undefined”。

    调用object.greet(),方法内部的greet()的this是指向object,因为greet()是一个常规函数,所以也就能调用到object中的who。

    但是farewell()是箭头函数,因此箭头函数内部的this始终指向外部,也就是object的外部。

    六、棘手的长度

    var length = 4;
    function callback() {
      console.log(this.length); // 输出的是?
    }
    
    const object = {
      length: 5,
      method(callback) {
        callback();
      }
    };
    
    object.method(callback, 1, 2);

    输出的是4.

    callback()使用内部的常规函数进行调用method(),因为常规函数callback()在调用期间this等于全局对象,this.length等于window.length。

    七、调用参数

    var length = 4;
    function callback() {
      console.log(this.length); // 输出的是?
    }
    
    const object = {
      length: 5,
      method() {
        arguments[0]();
      }
    };
    
    object.method(callback, 1, 2);

    打印输出的是3.

    obj.method(callback,1,2)调用时需要三个参数,callback,1和2。结果,arguments内部的特殊变量method()是具有以下结构的类似数组的对象:

    {
      0: callback,
      1: 1, 
      2: 2, 
      length: 3 
    }

    也就是:

    arguments[0]() == callback() == this指向arguments == arguments.length == 3

    所以输出了3.

    八,概括

    看完上面的七个问题,是不是对this有了更深刻的印象和理解呢。函数的调用是执行构成函数主体的代码,或者只是调用该函数。

     

  • 相关阅读:
    SpringBoot_10_打成jar包后使用外部配置文件中的配置来启动工程
    SpringBoot_09_使用jar包中配置的Bean(starter配置)
    猪齿鱼_03_领域模型
    Git_学习_11_Git rebase合并提交信息
    猪齿鱼_02_微服务组件间联系
    猪齿鱼_01_环境搭建(三)_整合业务服务
    猪齿鱼_01_环境搭建(二)_微服务支撑组件部署(Docker形式)
    【BZOJ】3996: [TJOI2015]线性代数
    【BZOJ】3994: [SDOI2015]约数个数和
    【BZOJ】3993: [SDOI2015]星际战争
  • 原文地址:https://www.cnblogs.com/liao123/p/14733107.html
Copyright © 2011-2022 走看看