1. 面試官:聊聊 this 指向問題

        共 3788字,需瀏覽 8分鐘

         ·

        2021-04-24 23:52

        136f972417d34070f80afbc4683adbaf.webp

        什么情況下會涉及 this
        • 函數(shù)作用域的情況下,才會有 this 綁定問題
        • 或者 class
        • 使用 call,apply, bind
        1. 嚴(yán)格模式 "use strict"
        2. 非嚴(yán)格模式
        嚴(yán)格模式下的 this 指向問題
        1. 普通函數(shù),this 指向 undefined,不使用 call,bing,apply 改變其 this 指向的情況下
        console.log("window===>",this)?//?Window?對象
        function?foo()?{
        ????function?bar()?{
        ????????console.log("bar?===>",this)?//?undefined
        ????}
        ????console.log("foo",?this)?//?undefined
        ????return?bar
        }
        var?bar?=?foo();

        bar()

        var?a?=?()?=>?{
        ????console.log("a===>",?this)?//?window?對象

        ????var?b?=?()?=>?{console.log("b===>",?this)}
        ????b()?//?window?對象

        ????function?c()?{console.log("c===>",?this)}
        ????c()?//?undefined
        }

        a()
        1. 箭頭函數(shù):在不使用 call,apply,bind 改變 this 情況下,this 指向 window
        "use?strict";

        var?a?=?()?=>?{
        ????console.log("a===>",?this)?//?window?對象

        ????var?b?=?()?=>?{console.log("b===>",?this)}
        ????b()?//?window?對象

        ????function?c()?{console.log("c===>",?this)}
        ????c()?//?undefined
        }

        a()
        非嚴(yán)格模式下
        1. 普通函數(shù),this 指向 window,不使用 call,bing,apply 改變其 this 指向的情況下
        function?foo()?{
        ????function?bar()?{
        ????????console.log("bar?===>",this)?//?window
        ????}
        ????console.log("foo",?this)?//?window
        ????bar()
        }
        foo();
        1. 箭頭函數(shù):在不使用 call,apply,bind 改變 this 情況下,this 指向 window
        var?a?=?()?=>?{
        ????console.log("a===>",?this)?//?window

        ????var?b?=?()?=>?{console.log("b===>",?this)}
        ????b()?//?window

        ????function?c()?{console.log("c===>",?this)}
        ????c()?//?window
        }

        a()
        非嚴(yán)格模式下,this 指向問題

        在一個(gè) obj 中定義一個(gè)函數(shù):

        var?a?=?"Ken"
        var?obj?=?{
        ????a:?"小仙女",
        ????fn:?function()?{console.log("fn===>",?this.a)}
        }

        obj.fn()?//?"小仙女"?//?此時(shí)?this?指向?obj

        //?變體?1
        var?fn?=?obj.fn?
        fn()?//?"Ken"?此時(shí)?this?指向?window

        //?變體?2

        var?a?=?"Ken"
        var?obj?=?{
        ????a:?"小仙女",
        ????fn:?()?=>?{console.log("fn===>",?this.a)}
        }

        obj.fn()?//?"Ken"?this?指向?window

        var?fn?=?obj.fn
        fn()?//?“Ken”?this?指向?window

        //?變體?3

        var?a?=?"Ken"
        var?obj?=?{
        ????a:?"小仙女",
        ????b:?{
        ????????a:?"===>obj.b",
        ????????fn:?function()?{console.log("obj.b===>",?this.a)}
        ????}
        }

        obj.b.fn()?//?"===>obj.b"?this?指向?obj.b

        var?fn?=?obj.b.fn
        fn()?//?Ken?this?指向?window

        //?變體?4

        var?a?=?"Ken"
        var?obj?=?{
        ????a:?"小仙女",
        ????b:?{
        ????????a:?"===>obj.b",
        ????????fn:?()?=>?{console.log("obj.b===>",?this.a)}
        ????}
        }

        obj.b.fn()?//?"Ken"?this?指向?window

        var?fn?=?obj.b.fn
        fn()?//?"Ken"?this?指向?window
        在嚴(yán)格模式下:
        "use?strict";
        var?a?=?"Ken"
        var?obj?=?{
        ????a:?"小仙女",
        ????fn:?function()?{console.log("fn===>",?this.a)}
        }

        obj.fn()?//?"小仙女"?//?此時(shí)?this?指向?obj

        //?變體?1
        var?fn?=?obj.fn?
        fn()?//?Uncaught?TypeError:?Cannot?read?property?'a'?of?undefined


        //?變體?2

        "use?strict";
        var?a?=?"Ken"
        var?obj?=?{
        ????a:?"小仙女",
        ????fn:?()?=>?{console.log("fn===>",?this.a)}
        }

        obj.fn()?//?“Ken”?this?指向?window

        var?fn?=?obj.fn
        fn()?//?"Ken"?this?指向?window

        //?變體?4

        ????????"use?strict";
        var?a?=?"Ken"
        var?obj?=?{
        ????a:?"小仙女",
        ????b:?{
        ????????a:?"===>obj.b",
        ????????fn:?()?=>?{console.log("obj.b===>",?this.a)}
        ????}
        }

        obj.b.fn()?//?"Ken"?this?指向?window

        var?fn?=?obj.b.fn
        fn()?//?"Ken"?this?指向?window

        從上面的觀察,以及實(shí)踐,我們或許可以得出一個(gè)結(jié)論:

        • 箭頭函數(shù) this 指向問題跟作用域有關(guān)系,他會沿著作用域鏈一層層往外找,最先找到那個(gè)具有作用域,就將 this 綁定在那個(gè)作用域上,如果找不到,就直接綁定在全局作用域上

        • 普通函數(shù)的 this 指向,取決于在那個(gè)對象上執(zhí)行,this 就執(zhí)行誰

        call,apply.bind

        發(fā)現(xiàn)個(gè)小問題,貌似 箭頭函數(shù)無法在執(zhí)行階段改變 this 指向問題

        var?a?=?"Ken"
        var?obj?=?{
        ????a:?"小仙女",
        ????b:?{
        ????????a:?"===>obj.b",
        ????????fn:?()?=>?{console.log("obj.b===>",?this.a)}
        ????}
        }

        obj.b.fn()?//?"Ken"?this?指向?window

        var?fn?=?obj.b.fn
        fn.call(obj)?//?"Ken"?this?指向?window
        fn.apply(obj)?//?"Ken"?this?指向?window
        fn.bind(obj)()?//?"Ken"?this?指向?window

        非箭頭函數(shù)情況:

        var?a?=?"Ken"
        var?obj?=?{
        ????a:?"小仙女",
        ????b:?{
        ????????a:?"===>obj.b",
        ????????fn:?function()?{console.log("obj.b===>",?this.a)}
        ????}
        }

        obj.b.fn()?//?"====>obj.b"?this?指向?obj.b

        var?fn?=?obj.b.fn
        fn.call(obj)?//?this?指向?obj?//?"小仙女"

        fn.apply(obj)?//?this?指向?obj?//?"小仙女"

        fn.bind(obj)()?//?this?指向?obj?//?"小仙女"
        class 類
        class?Person?{
        ????constructor(name)?{
        ????????this.name?=?name
        ????????console.log("Person===>",?this)?//?this?指向?qū)嵗龑ο?/span>
        ????}
        }


        var?p?=?new?Person("小仙女")


        瀏覽 27
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 欧美日本在线观看 | 天堂8在线视频 | 国产精品理论视频 | 国产黄色小说在线观看 | 春雨影院免费观看电视剧高清 |