| <<<Back 1 day (to 2017/05/23) | 20170524 |
avih | tor8: var x = {f: function() { return this }}; var y = [x.f(), (x.f)(), (0, x.f)(), x.f.valueOf()()]; is it correct behavior that y[0] and y[1] are x but y[2] and y[3] are not? 0 and 3 are obvious, 2 less obvious and 1 - not sure. should y[1] be x? | 16:23.26 |
| when is the valueOf being used, and when does it include the 'this' reference? especially i think i'd expect (x.f)() to _not_ return x, but it does with mujs (didn't test elsewhere yet) | 16:24.54 |
Robin_Watts | x.f() is (x.f)() | 16:25.44 |
| it's not x.(f(x)) | 16:25.53 |
| so I can't see why 0 and 1 should be any different. | 16:26.06 |
avih | the latter is an error, isn't it? | 16:26.09 |
| there's no 'f' which isn't part of 'x' | 16:26.25 |
Robin_Watts | indeed. | 16:26.34 |
| my point (badly made) was that bracketing won't matter. | 16:27.00 |
avih | so what are the rules to preserving a "dereferenced this" when evaluating expressions? (0, x.f)() seems to only take the value of f without the 'this', but (x.f)() does take the x this. how come? | 16:28.07 |
| Robin_Watts: how is (x.f) evaluated differently than (0, x.f) ? | 16:31.19 |
Robin_Watts | avih: That, I don't know. | 16:31.49 |
| In C, (0, x.f) and (x.f) would be the same. | 16:32.12 |
avih | well.. strictly speaking it's probably not the evaluation, as both of them end up with reference to x.f, but the former preserves the this when invoking the value, and the latter does not | 16:32.33 |
Robin_Watts | In javascript, I'd imagine that "(0, x,f)" is a "tuple of 0 and x.f" | 16:32.42 |
| and so 'this' is the tuple rather than the function. | 16:33.09 |
| but I could be wrong. | 16:33.20 |
avih | hmm... i need to find it at the spec, or ... ask tor8 which probably knows :p (or it could be a bug...) | 16:33.52 |
sebras | avih: I think looking at the spec might be faster as tor8 likely is out for a few hours. | 16:34.45 |
| avih: possibly until tomorrow. | 16:34.50 |
avih | (i wanted to use (x.f)() instead of x.f.call() and bumped into this) | 16:35.06 |
| sebras: i'll try, but it's huge and full of nuances :) | 16:35.46 |
sebras | avih: I know, I have read parts of it at one point. | 16:36.18 |
avih | easier to first compare it in different engines though. if mujs is the same as the rest, then i'll try the spec too | 16:36.45 |
| well.. firefox and node seem to agree with mujs. both show [true, true, false, false] for: var x = {f: function() { return this }}; [x == x.f(), x == (x.f)(), x == (0, x.f)(), x == x.f.valueOf()()]; | 16:38.57 |
tor8 | avih: x.f() and x["f"]() both call the function with this bound to the x | 23:23.12 |
| it's part of the syntax of how you call the function | 23:23.19 |
| if the expression is a member expression (x.y or x["y"]) then the left part of that expression (x) is bound to this when invoking the function | 23:23.56 |
| in all other ways of calling a function, 'this' is not bound to anything | 23:24.19 |
| (0,x.f)() will bind thus not bind this to x, since the expression used to call is a comma-expression | 23:25.18 |
| x.f.valueOf() will call valueOf with 'this' bound to x.f | 23:25.44 |
| i.e. the function | 23:25.57 |
| and x.f.valueOf()() is equivalent to (x.f.valueOf())(), where the expression used to call is another function call, leaving this unbound | 23:26.49 |
avih | tor8: so far that was my understanding too. the focus of my question was how come (x.f)() keeps the binding (it obviously does, in firefox and node too) | 23:29.51 |
tor8 | because the parenthesis is just setting precedence, it's not an expression type | 23:30.11 |
avih | so it doesn't "capture the value of" whatever is inside? | 23:30.37 |
tor8 | the parenthesis doesn't represent anything, it's just for overriding precedence rules | 23:32.14 |
avih | hmm... for some reason my hunch tells me it should be replace by the "value of" whatever is inside, but the "only precedence" does make sense too | 23:33.13 |
| +d | 23:33.22 |
tor8 | gotta go for tonight | 23:35.20 |
| probably won't be around much tomorrow | 23:35.25 |
avih | assuming i have such x.f, is there a simpler method to call f without args and unbound? (simpler than x.f.call(), (0||x.f)(), (0, x.f)(), x.f.valueOf()() ) | 23:35.31 |
| (or assigning it to a var and use that var) | 23:36.32 |
| the syntax of all the above is a bit ugly, and i prefer to not use another var or add unnecessary calls (such as with call or valueOf) | 23:37.44 |
| speed wise, (0,x.f)() seems measurably fastest from those | 23:38.30 |
| (and i understand why) | 23:38.42 |
| Forward 1 day (to 2017/05/25)>>> | |