This 整理

182 阅读2分钟

this 是什么?

this是指包含它的函数作为方法被调用时所属的对象。

因为js万物皆对象,所以可以理解成函数内的this指向是谁调用了这个函数(who.function) 函数外的this都指向window。

    let obj = {
        who
    };
    function who() {
        console.log(this)
    }
    who(); // window
    obj.who(); // obj

但是严格模式下禁止this关键字指向全局对象,所以this会指向undefined。

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

this指向问题

    let obj = {
        say: function(){
            let whoSay = function() {
                console.log(this)
            }
            return whoSay()
        }
    }
    obj.say() // window

这个this为啥是window?不是obj调的say吗?

其实这里虽然say是obj调的,但是实际上返回的是whosay这个函数,而whosay这个函数前面并没人去调用他就默认是window了。

以前我们会有一种写法去声明一个变量绑定this,然后就可以随时去使用这个this了

    let obj = {
        say: function(){
            const self = this;
            let whoSay = function() {
                console.log(self)
            }
            return whoSay()
        }
    }
    obj.say() // obj

现在出了ES6的箭头函数,这个this不再是谁调用就是谁的了,而是在哪个函数里面就是谁的了。

    let obj = {
        say: function(){
            let whoSay = () => {
                console.log(this)
            }
            return whoSay()
        }
    }
    obj.say() // obj
    let obj = {
        who
    };
    let who = () => {
        console.log(this)
    }
    who(); // window
    obj.who(); // window

call,apply,bind用来做什么?

call、apply、bind都是改变this指向的方法,只是使用方法不一样。 相同的是第一个参数都是this要指向的对象,后面则是传参。 不同则是传参方式不一样

    let obj = {};
    let f1 = function(a,b){
        console.log(this, a, b)
    };
    console.log(f1.call(obj,1,2)) // obj 1 2
    console.log(f1.apply(obj,[1,2])) // obj 1 2
    console.log(f1.bind(obj,1,2)()) // obj 1 2

apply和call传入的参数列表形式不同。apply接收arguments,call接收一串参数列表 bind 主要就是将函数绑定到某个对象,bind()会创建一个函数,返回对应函数便于稍后调用,而apply、call则是立即调用。

在非严格模式下,如果不传参数,或者第一个参数是null或nudefined,this都指向window。而严格模式下,this就指向谁,包括null和undefined,如果不传参数this就是undefined

不是call,apply,bind都可以改this的指向吗?箭头函数有没有什么影响?

    let obj = {};
    let f1 = function(){
        return this;
    };
    let f2 = () => {
        return this;
    };
    console.log(f1.call(obj)) // obj
    console.log(f2.call(obj)) // window

所以在箭头函数里就算使用call,apply,bind也改变不了他的指向,所以从某种意义上箭头函数的this可以理解成一个作用域。