最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 面试 | 你不得不懂的 JS this 指向

    正文概述 掘金(LinYIYI)   2021-03-23   533

    思维导图

    面试 | 你不得不懂的 JS this 指向

    this 的指向

    • 执行函数前有 '.' 点操作符的话,函数体中的 this 就指向前面的对象,没有就指向 window,严格模式下指向 undefined。这句话特别的重要,请记住
    • 函数没有直接调用者 this 指向全局对象(浏览器中是window,node中是 global)。如匿名函数等
    • 构造函数的 this 指向实例本身。
    • 箭头函数本身没有this的,箭头函数的 this 指向最近的非箭头函数 this,找不到就指向 window,严格模式下指向 undefined

    一、普通函数 this 的热身题

    热身题 1

    var name = '林一一'
    function fn(){
        var name = '林二二'
        return this.name
    }
    fn()    // 林一一
    

    再来看一下这句话:执行函数前有 '.' 点操作符的话,函数体中的 this 就指向前面的对象,没有就指向 window

    热身题 2

    var name = '林二二'
    var obj = {
        name: '林一一',
        fn: function () {
            return this.name
        }
    }
    console.log(obj.fn())   // '林一一'
    var fo = obj.fn
    console.log(fo())       // '林二二'     fo() ==> window.fo()
    

    再来看一下这句话:执行函数前有 '.' 点操作符的话,函数体中的 this 就指向前面的对象,没有就指向 window

    热身题 3,修改一下热身题 2

    var name = '林二二'
    var obj = {
        name: '林一一',
        fn: function () {
            var name = '小三'
            return function(){
                 return this.name
            }
        }
    }
    console.log(obj.fn()())   // 林二二
    var fo = obj.fn()
    console.log(fo())    // 林二二
    

    二、函数没有直接调用者

    函数没有直接调用者 this 指向全局对象(浏览器中是window,node中是 global)。如匿名函数等

    热身题 1

    var name = '林一一';
    !(function(){
       console.log(this.name)   // 林一一
    })()
    

    热身题 2

    var name = '林一一'
    var obj = {
        name : '二二',
        callback: function(){
            console.log(this.name)
        }
    }
    
    setTimeout(obj.callback,1000)
    /* 输出
    *   林一一
    */
    

    三、构造函数中的 this

    来读一下这句话:构造函数的 this 指向实例本身

    热身题 1

    function Fn(){
        var n = 0
        this.name = '林一一'
        this.age = 18
        this.getName = function(){
            return this.name
        }
    }
    
    Fn.prototype.getAge = function(){
        return this.age
    }
    
    Fn.x = '林二二'
    
    var f = new Fn()
    console.log(f.name)     // 林一一
    console.log(f.getName())     // 林一一
    console.log(f.getAge())        // 18
    console.log(f.n)    // undefined
    console.log(f.x)    // undefined
    

    四、箭头函数

    • 箭头函数本身没有 this,箭头函数的this继承上下文的,里面的 this会指向当前最近的非箭头函数的 this,找不到就是 window (严格模式是undefined)
    • 箭头函数的 this 始终指向函数定义时的 this,而非执行时

    热身题 1

    var name = '林一一'
    var obj = {
        name: '二二',
        a: () => {
            console.log(this.name)
        }
    }
    obj.a()
    
    /* 输出
    *   '林一一'
    */
    

    热身题 2

    var name = '林一一'
    var obj = {
        name: '二二',
        fn: function() {
            return () => {
                console.log(this.name)
            }
        }
    }
    obj.fn()()
    
    /* 输出
    *   '二二'
    */
    

    五、call,apply,bind 改变 this 的指向

    提示:所有的函数都是基于 Function 这个基类来创建的,同样拥有 Function 原型上面的方法

    • call,接受this的对象,和一组列表。applycall 一样,唯一不同的是 apply 接受的是一个包含多个参数的数组。bind 同样也是改变函数的 this 指向,只不过 bind 执行后会返回一个新的函数,新函数中参数来源于剩余的参数

    热身题

    var name = '林一一'
    var age = 18
    function fn(){
       return this.name
    }
    
    function p(){
        return {
            age: this.age,
            arg: arguments
        }
    }
    
    let obj = {
        name: '二二',
        age: 18
    }
    
    let o = {
        name: '三三'
    }
    
    fn()    // '林一一'
    fn.call(obj)    // '二二'
    fn.call(o)  //  '三三'
    p.call(obj, 12, 23, 45, 67) // {age: 18, arg: Arguments(4)}
    
    fn.apply(obj)    // "二二"
    p.apply(obj, [1, 2, 3, 4, 5])    // {age: 18, arg: Arguments(5)}
    
    fn.bind(obj)()  // "二二"
    p.bind(obj, 12, 23, 34)()   // {age: 18, arg: Arguments(3)}
    

    思考题

    1. 笔试题 this 指向问题

    var name = '林一一'
    var obj = {
        name: '林二二',
        show: function (){
            console.log(this.name)
        },
        wait: function () {
            var fn = this.show
            fn()
        }
    }
    obj.wait()  //  林一一
    

    2. 和闭包有关的 this 指向问题

    var n = 2 // -> 4 -> 8
    var obj = {
        n: 3,    // 6
        fn: (function(n){
            n*=2
            this.n+=2    // window 下的 n 变成 4
            var n = 5    // 这一步不会再重新声明,因为已经参数赋值,就不会再声明而是直接赋值 n = 5
            console.log("window.n", window.n)
            return function (m) {
                console.log("n:", n, "m", m)    // n:5  m:3  这里的 n 向上查找是 5   // 
                this.n*=2    // fn(3): 2 * 4 =8  //  obj.fn(3): 2 * 3 = 6 
                console.log(m + (++n))    // 3 + (++5) ++n 导致上级作用域的n变成了6    // 3 + (++6)
            } 
        })(n)
    }
    
    var fn = obj.fn;
    fn(3)    // 9
    obj.fn(3)    // 10
    console.log(n, obj.n)    // 8 6
    /* 输出
    * 9
    * 10
    * 8  6
    /
    

    结束


    起源地下载网 » 面试 | 你不得不懂的 JS this 指向

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元