this总结【1】—— this概览

1. this是什么

this这个单词是一个代词,所以this应当是 指代某些东西
搞清晰this的症结的地方,就是要搞清晰this指代了什么

那末this究竟指代了什么呢?
就像你日常平凡
指着一个苹果说 this is an apple
指着一个香蕉说 this is a banana

一样,this也会由于状况的差别而差别

在JavaScript中
根据通例邃晓,this的值是什么取决于函数怎样被挪用
但是,this的值是什么完整取决于对应函数被call时传入的第一个参数,而这平常是由js提早就预置好的

2. 函数怎样被挪用

2.1 通例邃晓

注重:这类要领能够揣摸平常状况下的this是什么

  1. 揣摸this值就看函数是怎样被挪用的[函数有全局挪用要领挪用]
  2. this指向挪用它的间隔近来的那一个
    // 例子
    function fn() {
        console.log(this)
    }

    let obj = {
        a: '',
        fn: fn
    }

    // 场景一
    fn() // window[浏览器] or global[node]

    // 场景二
    obj.fn() // obj

    // 场景一:全局挪用
    // 场景二:要领挪用

function VS method

  1. function xx(){…} 是function
  2. method某个对象下面的要领 如 obj = {fn:function(){…}} obj.fn() 叫做要领[method]

更细致的申明请看
深入浅出面向对象和原型【观点篇1】

    // test1
    function fn() {
        console.log(this)
    }

    let obj1 = {
        wrapper: {
            a: 'a',
            fn: fn
        }
    }
    obj1.wrapper.fn() // ?
    // fn()是被当作wrapper的要领被挪用的,所以this是wrapper
    // this指向挪用它的间隔近来的那一个

    // test2
    function executeCallback(cb) {
        cb()
    }

    executeCallback(obj1.wrapper.fn)
    // this是全局变量
    // 由于executeCallback函数是把cb当做全局函数举行挪用的
    // 不像是obj.cb(),假如obj.cb()就是要领挪用了

根据通例邃晓已能够处理大部分的口试、笔试题了,但假如想究this之基础,还需要经由过程call

2.2 用call邃晓

注重:经由过程对call的开端邃晓,你能够晓得this的值为何是如许的,但这类头脑不方便你猜this

起首,我们要清晰this在函数中的位置

    function fn1([this], parameter) {
        // this就是隐蔽的第一个参数,而且永远是第一个参数
        console.log(this)
    }

其次,我们要晓得call的语法

    fun.call(thisArg, arg1, arg2, ...)

OK,如今我们要晓得你在运用call的时刻
call传入的第一个参数能够指定(转变)fn1的第一个参数,也就是隐蔽的this

所以,为何直接全局挪用fn1时,打印出来的是window呢?
由于js已帮你call了

    // 你写的代码
    fn1()

    // 在你写上面代码的时刻,js帮你写了一行你看不到的代码
    fn1().call(undefined)

    // 你能够回问:如许打出来的值应当是undefined呀
    // 但浏览器有个机制
    // 假如你传的 thisArg 就 null 或许 undefined,那末 window 对象就是默许的 context(严厉形式下默许 context 是 undefined)

我们从新来对待一下全局挪用和要领挪用,以及js是怎样用call指定this的

    // 例子
    function fn() {
        console.log(this)
    }

    let obj = {
        a: '',
        fn: fn
    }

    // 场景一
    fn() // window[浏览器] or global[node]
    // js帮你写的代码
    fn().call(undefined)

    // 场景二
    obj.fn() // obj
    // js帮你写的代码
    obj.fn().call(obj)

小测试(小圈套)

    let module = {
        x: 42,
        getX: function () {
            return this.x;
        }
    }

    let retrieveX = module.getX;
    console.log(retrieveX()); // undefined
    console.log(module.getX()) // 42

2.3 严厉形式下的this

严厉形式下只需要
注重一点就行,别的状况下与非严厉形式雷同

全局作用域里函数中的this是undefined

function test() {
    "use strict"
    console.log(this) 
}
test() // undefined

所以,在运用组织函数时假如忘了加new,this不再指向全局对象,而是报错,由于这就是函数的全局挪用

let People = function (name) {
    "use strict"
    this.name = name
}
People() // Cannot set property 'name' of undefined

3.几种庞杂状况中的this

3.1 数组中的this

function fn() {
    console.log(this)
}

arr[fn, fn2, fn3]

arr[0]() // ??

// answer:arr

// 剖析
// 数组也是对象的一种
// arr[0]() 能够看作 arr.0().call(arr)

3.2 嵌套函数中的this

// 例子一
function fn0() {
    function fn() {
        console.log(this);
    }

    fn();
}

fn0(); // fn中this是全局变量

// 例子二
let a = {
    b: function () {
        console.log(this) // {b:fn}
        function xx() {
            console.log(this) // window
        }
        xx()
    }
}
a.b()

3.3 setTimeout、setInterval中的this

document.addEventListener('click', function (e) {
    console.log(this);
    setTimeout(function () {
        console.log(this); // 这里的this是全局变量
    }, 200);
}, false);

3.4 事宜中的this

document.querySelector('div').addEventListener('click',function (e) {
    console.log(this) // <div></div>
})
// 事宜里的this指向的是触发事宜的DOM节点

3.5 运用new时的this

请看深入浅出面向对象和原型【番外篇——从新认识new】

4.总结

假如几种庞杂状况下的this你看完了,你应当会有迷惑
为啥我邃晓了全局挪用和要领挪用,但this的值依然和我揣摸的不一样呢?

我说过了,this的值是call的第一个参数,js已给许多this举行call了

所以,总结一下

  1. this的值是什么,你别猜,很能够会和你想的不一样
  2. console出来或许去看文档、看源码才是最稳妥的挑选
  3. 假如你非要猜,就套用一下我这篇博客写到的这几种状况
  4. 假如你怕猜错,又要用到this,很简单,直接用bind去强迫指定this

关于call/apply/bind 请看
this总结【2】—— call/apply和bind

5.参考

this 的值究竟是什么?一次说清晰

    原文作者:bluesboneW
    原文地址: https://segmentfault.com/a/1190000013337410
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞