As of ES2015 (ES6), functions have proper names (including an official name
property), and names are assigned when the function is created in a variety of ways
Allen Wirfs-Brock has replied on the es-discuss list with the objections that prevented the TC39 consensus on the obj.foo = function() { }
form:
...for
cache[getUserSecret(user)] = function() {};
it would leak the secret user info as the value of name
and for
obj[someSymbol] = function() {}
it would leak the Symbol value as the value of name
and for
table[n]=function() {}
name would likely be a numeric string
There are counters to those objections (particularly the last one, which is extremely weak; there are many other ways a function is automatically assigned a numeric string name), but that's not the point; the point is that those were the objections raised.
He also added that the IsPropertyReference operation that would be required (where currently there's just an IsIdentifierRef)...
...is a runtime operation and the new semantics require runtime determination of the name value. This is all extra runtime work that may slow down the creation of function closures that appear within loops.
So all in all, apparently at the time the decision was taken, those objections carried the day (and quite possibly would now as well), which is why this form doesn't automatically name functions whereas so many others do.
I went through reading the Allen Wirfs-Brock answers, and he explicitly talks about possible security issues. I personally agree with him.
There may also be security concerns. The name property potentially leaks via the function object the name of the variable it is initially assigned to. But there isn't much someone could do with a local variable name, outside of the originating function. But a leaked property name potentially carries a greater capability.
It seems like the objections he talks about have something to do with it. If TC39 didn't explained further it's decision, it's going hard to find out why did they leave it like that :).
I'mn sorry I can't help you further.
I'm not sure there is a specific reason.
obj.foo = function (){};
first creates a reference for the function expression in obj, then binds foo to this reference which has already a (readonly) name.
So:
obj.fooC = (new Function ());
console.log(obj.fooC.name);//'anonymous'
obj.fooFE = function (){};
console.log(obj.fooFE.name);//''
obj.fooNFE = function a_name (){};
console.log(obj.fooNFE.name);//'a_name'
is normal behaviour.
Is there any restriction to write :
obj.foo = (function foo(){});