-1

In trying to understand the 'this' keyword in JavaScript, I've looked at many resources, including the answers on this popular Stack Overflow question: How does the "this" keyword work?

I don't know if I am misunderstanding something, but everything I've read seems to be incomplete and missing a rule: Even though functions are objects, 'this' is treated differently for function-objects vs. other objects.

Consider the following code:

var object = {};
object.name = "object";
object.logMyName = function() { 
  console.log(this.name);
};
object.logMyName();

Because a function ('logMyName') is called on an object ('object'), 'this' is set to the object ('object') upon which the function ('logMyName') was called.

Now consider the following code:

var funcObject = function() {};
funcObject.name = "funcObject";
funcObject.logMyName = function() { 
  console.log(this.name);
};
funcObject.logMyName();

Although a function ('logMyName') was called on an object ('funcObject'), 'this' is not set to the object ('funcObject') upon which the function ('logMyName') was called.

Why does this discrepancy between types of objects exist, and why is it rarely/never discussed?

Community
  • 1
  • 1
cowlinator
  • 4,270
  • 4
  • 27
  • 41
  • 1
    The 2nd code example uses an anonymous function. When I drop that code into jsfiddle, then "this.name" returns blank. The name property appears to be read-only & can't be set with `funcObject.name = "funcObject";` – Clomp Mar 26 '16 at 00:26

1 Answers1

5

That's because functions have a special name property.

The value of the name property is an String that is descriptive of the function. The name has no semantic significance but is typically a variable or property name that is used to refer to the function at its point of definition in ECMAScript code. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

That property is not writable, so your assignment is ignored.

However, since it's configurable, you can redefine it:

var funcObject = function() {};
Object.defineProperty(funcObject, 'name', {
  configurable: true,
  value: "funcObject"
});
funcObject.logMyName = function() { 
  console.log(this.name);
};
funcObject.logMyName(); // logs "funcObject"

Note some old browsers implemented it as non-configurable before ES6 standardized it as configurable, so the code above might not work.

Oriol
  • 225,583
  • 46
  • 371
  • 457
  • You're right. I thought that this was a symptom of 'this' behavior, but it appears that it was simply due to read-only properties. I was not aware that JavaScript had such a thing as read-only properties. Which unfortunately fail silently. – cowlinator Mar 26 '16 at 00:31