美文网首页
【js基础】几道this题

【js基础】几道this题

作者: SophieRabbit | 来源:发表于2020-07-27 20:14 被阅读0次

    第一道

    function test() {

        console.log(this.name);

    }

    var obj = {

        name: 'whoami',

        getName: test

    };

    var name = 'which';

    obj.getName();

    var output = obj.getName;

    output();

    我的答案:'whoami',  'which'

    对 (在严格模式下,答案为'whoami', undefined)

    第二道

    function test() {

        console.log(this.name);

    }

    var obj = {

        name:'whoami',

        getName: test

    };

    setTimeout(obj.getName,1000);

    我的答案:'whoami'

    错。答案为undefined

    第三道

    function test(x){

        this.x = x;

        return this;

    }

    var x = test(5);

    var y = test(6);

    console.log(x.x);

    console.log(y.x);

    我的答案: undefined, undefined

    对,错。答案为undefined,6

    解答:

    第一道题涉及的知识点:this绑定的两种方式以及绑定丢失

    第二道题…:this隐式绑定、绑定丢失

    第三道题…:this默认绑定、变量提升、同名变量知识

    在彻底明白上面结果是如何得来前,先具体讲解下this的绑定时间、四种绑定方式以及其优先级:

    this存在于所有函数中,在函数调用时被赋值

    1.默认绑定

    此时this的指向是window对象(非严格模式下,严格模式下 默认绑定this === undefined)

    function test() {

        console.log(this);

    }

    test();  // this === window

    2.隐式绑定

    此时this指向包含它的对象

    function test(){

        console.log(this);

    }

    var obj = {

        getValue: test

    };

    obj.getValue();   // obj {}

    3.显式绑定

    就是使用call、apply或bind方法来显式绑定

    function test() {

        console.log(this);

    }

    var obj = {

        name: 'whoami'

    };

    test.call(obj);  // obj {name: 'whoami'}

    4.new绑定

    就是使用new关键字会存在this的绑定

    functionTest() {

        console.log(this);

    }

    var test = new Test();  // Test(){}

    这四种方式的优先级如下(从高到低依次):

    new绑定 > 显式绑定 > 隐式绑定 > 默认绑定

    绑定丢失

    凡事总有例外,this的绑定也是,下面说明几种例外:

    1、赋值带来的绑定丢失

    function test() {

        console.log(this);

    }

    var obj = {

        getValue: test // 此处是隐式绑定

    };

    var output = obj.getValue; // 赋值

    output(); // 赋值导致绑定丢失,此时应用默认绑定

    /**

    * (output = obj.getValue)() 等价于output()

    */

    /**

    * setTimeout() 实际上类似于

    * function setTimeout(fn, delay) {

    * }

    * fn = obj.getValue故也会导致绑定丢失,应用默认绑定

    */

    setTimeout(obj.getValue, 1000);

    2、null或undefined带来的绑定丢失

    function test() {

        console.log(this);

    }

    test.call(null);   // this === undefined(严格模式下)

    test.call(undefined);   // this === window(非严格模式下)

    test.call(2);  // 此时应用显式绑定,因为除了Null、Undefined类型之外的其他类型在进行操作时都会在底层产生该类型的对象

    再回头看三道面试题:

    第一道是隐式绑定,不过存在赋值导致绑定丢失,应用默认绑定

    第二道同样如此

    第三道是默认绑定,不过主要考察点在于变量提升以及同名变量的处理

    就具体分析下第三道面试题:

    function test(x) {

        this.x = x;

        return this;

    }

    var x = test(5);

    var y = test(6);

    console.log(x.x);

    console.log(y.x);

    因为全局变量会自动成为window的属性、变量和函数提升的问题,上面的代码实际上如下:

    function test(x) {

        // this === window,所以this.x = window.x

        this.x = x;

        return this;

    }

    var x, y;

    x = test(5);

    // 此时window.x === x, x === widnow

    y = a(6);

    // 此时x === 6

    // x.x 此时为6.x, 故为undefined

    console.log(x.x);

    // y.x 此时为window.x

    console.log(y.x);

    下面补充下其他情况this指向:

    函数内部函数中this指向的问题,在内部函数中this使用默认绑定

    function test() {

        (function() {

            console.log(this);

        })();

    }

    test(); // this === window

    ES6中增加了箭头函数,该函数有两个作用:

    简写函数定义

    this指向明确,指向该函数所在作用域的this的值

    实例:

    var test = () => console.log(this);

    test(); // this === window

    test.call({}); // this === window

    相关文章

      网友评论

          本文标题:【js基础】几道this题

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