Assigning a function to a member of a number, why is this not a mistake?

From my Chrome interpreter:

a = 3; // OK, of course. af = function() { return 4; }; // OK. To a number? Ok a; // Prints 3 af(); // f is not a function. af; // Undefined 

Of course, a not an object, and I cannot assign new members to what is not an object. But why does the interpreter swallow the af assignment if after that the method or member does not exist yet?

+6
source share
2 answers

If you look at 8.7.2 ECMA 5.1 , you will notice this note below:

The object that can be created in step 1 is not available outside the above method. An implementation may decide to avoid actually creating this transition object. The only situations where such an actual property assignment that uses this internal method can have a visible effect when it either calls the access function or violates the established Throw error check. When Throw is true, any property assignment that would create a new property on the transition object throws an error.

Step 1 - Let O be ToObject(base).

If you look at the ToObject() method in 9.9 , you will find these two rows in the table:

  • room

Create a new Number object whose internal [[PrimitiveValue]] property is set to the value of the argument. See 15.7 for a description of Number objects.

  • An object

The result is an input argument (no conversion).


It looks like this when you try to set a function to a number, it actually happens (albeit in the form of noop), it becomes inaccessible after the assignment due to the assignment executed on the internal transition object. When you do this on a regular object, it returns the actual object, so the assignment makes sense.

+2
source

There really was no good reason why it was not forbidden; it could have been easy if it had been realized when the language was developed.

But why was this implemented without errors? Because it perfectly reflects what happens when you access a property on a primitive: it implicitly receives a throw to the object. It doesn’t matter if you use the property reference for assignment or retrieval, there is an object there. The assignment will work as usual, even if the coercive object is thrown right away.

We even see that when we provide an inherited accessor for this object on its prototype:

 "use strict"; Object.defineProperty(Number.prototype, "f", { set: function(value) { console.log(typeof this+" "+this+" got "+value+" assigned to .f"); }, get: function() { console.log(typeof this+" "+this+" .f property was accessed"); return function() { console.log("method called on "+typeof this+" "+this); }; }, configurable: true }); (3).f = "test value"; (3).f(); 
+2
source

Source: https://habr.com/ru/post/1012546/


All Articles