JavaScript学习日记 : Day11 - 函数绑定

当object中的function作为callback function传递给setTimeout时,会发生this指向丢失的问题,今天的文章就来探讨要如何解决。

this指向丢失

直接举个例子:

let car  = {
    color:"blue",
    getColor() {
        console.log(this.color);
    }
}

setTimeout(car.getColor, 1000); // getColor is not defined

这是因为setTimeout中的car.getCar只是call by reference,所以这边this会预设的指向全域(window),这边有两个解决方法:

浏览器中的setTimeout与node.js中有些不同,浏览器会预设把this指向window,而node.js会把this指向time objetc,但这不影响这边我们要学习的函数绑定。

包装函数

不直接以getColor当作callback function,而是在外面包装一个函数:

let car  = {
    color:"blue",
    getColor() {
        console.log(this.color);
    }
}

setTimeout(() => car.getColor(), 1000); // blue

在callback function中因为找不到car变数,所以会往上一层执行环境寻找car变数,这样一来就不会有this丢失的问题了。

但是这个方法存在一个风险,就是今天如果在一秒的时间还没到之前,car变数发生了变化,会导致getColor无法顺利取得,这时候就要使用1.2的方法了。

let car  = {
    color:"blue",
    getColor() {
        console.log(this.color);
    }
}

setTimeout(() => car.getColor(), 1000); // car.getColor is not a function

car = "new value"

bind

bind是function的一个方法,之後文章会介绍bind、apply与call的比较,简单来说bind可以绑定function的this值。

let car  = {
    color:"blue",
    getColor() {
        console.log(this.color);
    }
}

setTimeout(car.getColor.bind(car),1000);

测试一下如果今天改变了car的值:

let car  = {
    color:"blue",
    getColor() {
        console.log(this.color);
    }
}

setTimeout(car.getColor.bind(car),1000); // blue

car  = "new value"

<<:  Day 23 - 前端开发工具 - HBuilder X

>>:  [Day 11] 核模型 - 支持向量机 (SVM)

强人PM与敏捷相遇 -2

虽然想把这些敏捷有关的精神导入团队中,但自己仍不愿意对外说在执行敏捷的流程。其中一个最大的差异,是在...

Day29 RealmSwift

RealmSwift 今天要介绍 Realm 的 CRUD ,也就是新增、读取、修改、删除的基本操作...

Day30-1 - GitLab CI 可以怎麽重构及整理 .gitlab-ci.yml 让内容更好了解?

随着专案的演进,当团队导入 GitLab CI 工作流程之後,通常会是陆续的针对专案需要增加更多的流...

狗狗币的技术与理想的深入解析

或许你想问我 狗狗币有突出的技术吗? 它不是只是照抄程序码而诞生的加密货币吗? 事实并非如此, 我认...

Day-25 Deadlock

Deadlock tags: IT铁人 介绍 Deadlock是Multi-process常产生的问...