safe-touch
safe-touch copied to clipboard
Lost this context
const a = {
_b: 1,
b() {
return this._b
}
}
console.log(a.b()) // 1
console.log(safeTouch(a).b()()) // undefined or type error (strict mode)
Hi @hax ~or 贺老?~
I'm sorry that preserving this context might not be possible under current design of safe-touch.
Let me explain:
As you already know, if you want to retrieve property, apply the wrapped value as a function, e.g. safeTouch(a).b()
. There is an explicit function call. In fact, every step in the property chain is a function call.
Then let's add such function to the snippet you provided:
function test() {
return a.b
}
test() // undefined
Now we have proved that function returned from other scope could not preserve this context, even if it tried to chain.
Some people might ask - what about use bind/apply/call
?
There does exist other libs that was implemented in that way, but they will create extra function, which is against one of design principles of safe-touch, i.e. safeTouch(original).key() === original.key
.
This principle keeps safe-touch pure and simple.
But I have to admit: one the original goal of safe-touch was, if all property exists, user should be able to touch the object as if it was not wrapped by safe-touch. That is,
safeTouch(a).b()() === 1
in the case of your snippet.
Any alternative lib choices?
Use safe-navigation-js. It's quite similar to safe-touch, except
- Retrieves property value with
.$
, in a property way. If you have an object with exactly$
property on it, life gets hard. - It binds this for function.
safeNavigation(a).b.$ !== a.b
.
How much do we need that functionality?
In my daily work, I don't write objects with function properties with this in it and use it in the way like obj.func()
.
If I had to, I'd write arrow functions, which works with safe-touch.
IMOP, the case in your snippet does not look like an actual need nowadays, at least not to me. (no offence)
Thank you for your issue anyway!