JavaScript当函数在循环中调用时,这是未定义的



我有下面的代码,在注释中解释了行为。"this"在匿名函数中是undefined的原因是什么?

const getLength = (str) => {
return str.length
}
const getDefaultValues = () => {
const valueGetters = {
A: {
AA: {
xpath: 'path',
getValue: function () {
return getLength(this.xpath) // <---- this is not undefined and returns value
}
},
AB: {
xpath: 'path',
getValue: function () {
return getLength(this.xpath) // <---- this is not undefined and returns value
}
},
AC: {
xpath: 'path',
getValue: function () {
return getLength(this.xpath) // <---- this is not undefined and returns value
}
},
AD: {
xpath: 'path',
getValue: function () {
return getLength(this.xpath) // <---- this is not undefined and returns value
}
},
AE: {
xpath: 'path',
getValue: function () {
return getLength(this.xpath) // <---- this is not undefined and returns value
}
},
GROSS: function () { // <--- when called in the loop, this returns 0 because all the ternary operators evaluate to false and return 0
// console.log('this', this) // <---- this is undefined
const aa = this?.AA ? this.AA.getValue() : 0
const ab = this?.AB ? this.AB.getValue() : 0
const ac = this?.AC ? this.AC.getValue() : 0
const ad = this?.AD ? this.AD.getValue() : 0
const ae = this?.AE ? this.AE.getValue() : 0
return aa + ab + ac + ad + ae
}
}
}
console.log('Calling without looping', valueGetters.A.GROSS()) // <--- This prints the correct value for gross without any problem
// get the numerical values from the getters
const valueEntries = Object.entries(valueGetters).map(([key, defaultValueGetter]) => {
return [
key,
Object.entries(defaultValueGetter).map(
([defaultValueKey, defaultValue]) => [
defaultValueKey,
typeof defaultValue === 'function' ? defaultValue() : defaultValue.getValue() // <--- I suspect that the problem is with this line
]
)
]
})
return makeObject(valueEntries)
}
const makeObject = (arr) => {
return Object.fromEntries(
arr.map(([key, val]) => (Array.isArray(val) ? [key, makeObject(val)] : [key, val]))
)
}
console.log(getDefaultValues())

您只是以defaultValue()的形式调用函数,它不提供this上下文。您需要显式地提供this值,这可以通过.call()来实现。

typeof defaultValue === 'function' ? 
defaultValue.call(defaultValueGetter) : 
defaultValue.getValue()

最新更新