Я не думаю, что «наследовать» - правильное слово.
При каждом вызове функции присутствует скрытый this
аргумент («значение this», иногда называемое «получатель»). Значение this зависит от того, как вызывается функция.
this
был добавлен в язык для включения Java -подобного объектно-ориентированного синтаксиса. Например:
class Point {
constructor(x, y) {
this.x = x
this.y = y
}
getX() {
return this.x
}
}
... или используя функцию конструктора:
function Point(x, y) {
this._x = x
this._y = y
}
Point.prototype.getX = function() {
return this._x
}
Итак, this
позволяет программисту удобно ссылаться на объект, для которого вызывается функция как метод:
const a = new Point(1, 2);
console.log(a.getX());
... но, к сожалению, есть дополнительная сложность вокруг this
в JavaScript.
Сложность проистекает из способности вызывать функции другими способами, а не как метод объекта (подробности см. MDN ). Например:
function myFunction() {
console.log(this) // `undefined` in strict mode, `window` in non-strict
}
myFunction() // `myFunction` is not called as a method!
В первом примере приведен пример вызова функции иным способом, чем в методе: каким должно быть значение this в функции, предоставляемой в качестве обратного вызова для setInterval
? Как это происходит, значение по умолчанию this
в функциях, переданных в setInterval
, является глобальным объектом (поэтому window
в данном случае).
... и это объясняет идиому, который мы видим в используемом в Ваш код: присваивание значения this
переменной that
(я переименовал ее из "countup" в вашем примере) для обратного вызова, чтобы закрыться. Таким образом, мы можем ссылаться на значение this внешней лексической среды, начиная с внутри обратного вызова, всякий раз, когда он вызывается.
var countup = {
counter: 0,
start: function() {
var that = this
setInterval(function() {
that.counter++
}, 1000)
}
}
Ваш второй пример делает то же самое, но в более современном JavaScript. Функции стрелок всегда используют значение this лексического окружения, в котором они объявлены («лексический this»). Таким образом, мы можем покончить с промежуточной переменной that
:
var countup = {
counter: 0,
start: function() {
setInterval(() => this.counter++, 1000)
}
}
Внутри setInterval
значение по умолчанию this
является глобальным объектом, но ничто не мешает вам использовать другую эту значение с помощью функции стрелки или вызов , применение или связывание . Это просто ссылка на объект (или null
, или undefined
). Так что если есть общее состояние, которое вы хотите обновить с setInterval
, то вы можете сделать это с помощью this
. Является ли это хорошей идеей или нет, субъективно. Лично я стараюсь избегать this
, потому что я думаю, что это усложняет ситуацию, но многие разработчики думают об обратном.
По моему опыту, this
имеет тенденцию больше использоваться в кодовых базах, использующих объектную ориентацию на основе классов, поскольку в этих кодовых базах есть методы, которые часто должны ссылаться на состояние объекта, для которого они были вызваны.
class Clock {
start() {
setInterval(() => this.tick(Date()), 1000) // using lexical `this`!
}
tick(time) {
console.log(time)
}
}
const c = new Clock
c.start()