JavaScript系列 — this关键字

JavaScript中this关键字的定义:

this是JavaScript语言中的一个关键字 它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用

普通函数/对象/构造函数里的函数的定义及其对应的调用方式

  • 普通函数里函数的定义和调用
function fn(){
    let name = "John"
    let age = 18
    function say(){
        console.log(this)
    }
    say() / return say() 这两种写法都是在fn()里面调用say()
}
fn() // windowfunction fn(){
    let name = "John"
    let age = 18
    return ()=>{
        console.log(this)
    }
}
fn()() // window
复制代码
  • 构造函数里函数的定义和调用
function Person(name, age) {
    this.name = name;
    this.age = age;
    this.say = function () {
        console.log(this);
    }
}
var p = new Person("John",18)
p.say() // Person {name: "John", age: 18, say: ƒ}
复制代码
  • 对象里函数的定义和调用
var obj = {
    name: "John",
    age: 18,
    say: function () {
        console.log(this)
    }
}
obj.say() // {name: "John", age: 18, say: ƒ}var obj = {}
obj.name = "John"
obj.age = 18
obj.say = function () {
    console.log(this)
}
obj.say() // {name: "John", age: 18, say: ƒ}
复制代码

判断this的指向(隐式绑定、window绑定)

this的指向,始终坚持一个原理:this永远指向最后调用它的那个对象。

这个对象怎么判断,如果有.就是.前面的,如果没有则下默认是window

隐式绑定(有.的)

var name = "windowsName";
var a = {
    name: "Cherry",
    fn : function () {
        console.log(this.name);
    }
}
a.fn(); // Cherry
window.a.fn(); // Cherry
复制代码

window绑定(没有.的)

var name = "windowsName";
var a = {
    name: "Cherry",
    fn : function () {
        console.log(this.name);    
    }
}
var f = a.fn;
f();  // windowsName
复制代码

箭头函数的this指向

记住一句话:如果箭头函数被普通函数包含(注意不是obj),则this指向跟着最近一层普通函数指向;如果没有被普通函数包含,则箭头函数的this指向window

let obj = {
    a: 2,
    c: {
        a: 3,
        d: () => {
            console.log(this);
            console.log(this.a);
        }
    }
}
obj.c.d(); // window, undefined
复制代码

setTimeout里的this指向

  • 如果setTimeout里面是普通函数形式,则this永远指向window
  • 如果setTimeout里面是箭头函数形式,则this就跟着最近一层普通函数的this指向

改变this的指向

改变this指向有两种方法:

把this用一个变量存起来

这里原本setTimeout里面的普通函数的this会指向window,而我们需要其指向F()

var num = 0;
function F (){
    var that = this;    //将this存为一个变量,此时的this指向f
    this.num = 1,
    this.getNum = function(){
        console.log(this.num);
    },
    this.getNumLater = function(){
        setTimeout(function(){
            console.log(that.num);    //利用闭包访问that,that是一个指向obj的指针
        }, 1000)
    }
}
var f = new F(); 
f.getNum();//1  打印的是obj.num,值为1
f.getNumLater()//1  打印的是obj.num,值为1
复制代码

显式绑定(call/apply/bind)

这里greet()函数和user对象是分开的,没有任何包含关系,怎么让greet()能够访问到user里的name呢

function greet (person1, person2, person3) {
  console.log(`Hello, my name is ${this.name} and I know ${person1}, ${person2}, and ${person3}`)
}

const user = {
  name: 'Tyler',
  age: 27,
}

const people = ['John', 'Ruby', 'Deck']
复制代码

call()方法

函数.call(对象/函数,参数1,参数2,参数3,…)

greet(user,people[0],people[1],people[2])
// Hello, my name is Tyler and I know John, Ruby, and Deck
复制代码

这样需要将数组的一个一个元素一个个写入显得太麻烦了,于是我们引入apply()方法

apply()方法

函数.apply(对象/函数,[数组])

greet(user,people)
// Hello, my name is Tyler and I know John, Ruby, and Deck
复制代码

bind()方法

函数.bind(对象/函数,参数1,参数2,参数3,…)

参考文章

JavaScript中的this

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享