前端从入门到精通---this

  • this 并不是指向函数本身
  • this 在任何情况下都不指向函数的词法作用域
  • this 是在运行时进行绑定的, 而并不是在编写时绑定, 它的上下文取决于函数调用时的各种条件
  • this 的绑定和函数声明的位置没有任何关系, 只取决与函数的调用方法

默认绑定

当函数被单独定义和调用的时候, 应用的规则就是绑定全局变量 window
function person(){
    var weight = 120
    console.log(this) // window
    console.log(this.weight) // undefied
}

person() // window.person() person 函数绑定在 window 对象上

PS: 这里的 this对象指的是 window 对象

隐式绑定

函数调用时拥有一个上下文对象, 就好像这个函数是属于该对象的一样, 必须在一个对象内部包含一个指向函数的属性, 并通过这个属性间接引用函数, 从而把 this 间接(隐式)绑定到这个对象上。
var person = {
    height: 170,
    age: 25,
    weight: 120,
    eat: function () {
        console.log(this.height) // 170
        console.log('吃饭')
    },
    sleep: function () {
        console.log(this.weight) // 120
        console.log('睡觉')
    },
}

person.eat() // window.person.eat()
person.sleep()  // window.person.sleep()

PS: 这里的 this对象指的是 person 对象

显式绑定

使用 bindapplycall 函数, 它接收的第一个参数即是上下文对象并将其赋给 this
var person = {
    height: 170,
    age: 25,
    weight: 120,
    eat: function () {
        console.log(this.height) // 170
        console.log('吃饭')
    },
    sleep: function () {
        console.log(this.weight) // 120
        console.log('睡觉')
    },
}

function test() {
    console.log(this.age)
}

test.call(person) // 这里把 person 作为对象传入, 结果为 25 

new 绑定

如果是一个构造函数, 那么用 new 来调用, 那么绑定的是新创建的对象。
function person(){
    this.weight = 120
    console.log(this) // person
    console.log(this.weight) // 120
}

var p = new person() // 如果不创建对象, 则 this 为 window 对象
console.log(p.weight) // 120

PS: 这里的 this 对象指的是 person 函数对象

  • this 遇到 return
function person(){
    this.weight = 120
    return {} // 返回一个空对象
}

var p = new person()
console.log(p.weight) // undefined
function person(){
    this.weight = 120
    return function(){} // 返回一个函数
}

var p = new person()
console.log(p.weight) // undefined
function person(){
    this.weight = 120
    return 1 || undefined || null // 返回一个非函数 
}

var p = new person()
console.log(p.weight) // 120

函数的的bindcallapply方法

  • call
call 可以用来调用所有者对象作为参数的方法, 能够使用属于另一个对象的方法。
call 可以接受多个参数, 以 , 分割。
var person = {
    height: 170,
    eat: function () {
        console.log(this.height) // 170
        console.log('吃饭')
    },
}

var p = person.eat
p.call(person)
var person = {
    height: 170,
    eat: function (age, weight) {
        console.log(age) // 25
        console.log(weight) // 120
        console.log(this.height) // 170
        console.log('吃饭')
    },
}

var p = person.eat
p.call(person, 25, 120)
  • apply
apply 方法和 call 方法有些相似, 它也可以改变 this 的指向。
apply 可以接受多个参数, 第二个参数必须是 数组 格式。
var person = {
    height: 170,
    eat: function () {
        console.log(this.height) // 170
        console.log('吃饭')
    },
}

var p = person.eat
p.apply(person)
var person = {
    height: 170,
    eat: function (age, weight) {
        console.log(age) // 25
        console.log(weight) // 120
        console.log(this.height) // 170
        console.log('吃饭')
    },
}

var p = person.eat
p.apply(person, [25, 120])

PS: 如果 callapply 的第一个参数写的是 null, 那么 this 指向的是 window 对象。

  • bind
bind 只有需要调用时才调用, 可以用来改变this 的指向。
bind 可以将参数在执行的时候添加, 也可以开始添加, 也可以拆开来在初始时和执行时分别添加。
bind 可以接受多个参数, 以 , 分割。
var person = {
    height: 170,
    eat: function () {
        console.log(this.height)
        console.log('吃饭')
    },
}

var p = person.eat
let bindFunc = p.bind(person) // 操作不执行
console.log(bindFunc)
/*
ƒ () {
    console.log(this.height) // 170
    console.log('吃饭')
}
 */
// 只有执行 bindFunc 函数才算调用
bindFunc()
var person = {
    height: 170,
    eat: function (age, weight) {
        console.log(age) // 25
        console.log(weight) // 120
        console.log(this.height) // 170
        console.log('吃饭')
    },
}

var p = person.eat
let bindFunc = p.bind(person, 25, 120) // 操作不执行
bindFunc()

let bindFunc2 = p.bind(person)
bindFunc2(25, 120)

// 也可以拆开来, 下面参数是相加的
let bindFunc3 = p.bind(person, 25)
bindFunc3(120)

总结:

  • 如果返回值是一个对象, 那么 this 指向的就是那个返回的对象, 如果返回值不是一个对象那么 this 还是指向函数的实例。
  • 还有一点就是虽然 null 也是对象, 但是在这里 this 还是指向那个函数的实例, 因为 null 比较特殊。

下一节我们将认识一下Javascript的原型对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值