I have the following code with the behavior explained in the comments. What could be the reason why "this"
is undefined
in the anonymous function?
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())
CodePudding user response:
You're just calling the function in the form defaultValue()
, which doesn't provide a this
context. You need to provide the this
value explicitly, which you can do with .call()
.
typeof defaultValue === 'function' ?
defaultValue.call(defaultValueGetter) :
defaultValue.getValue()