为什么 'this' 在与函数对象一起使用时会受到不同对待?

Why is 'this' treated differently when used with function objects?

为了理解 JavaScript 中的 'this' 关键字,我查看了很多资源,包括这个流行的 Stack Overflow 问题的答案: How does the "this" keyword work?

我不知道我是否误解了什么,但我读过的所有内容似乎都不完整并且缺少规则: 尽管函数是对象,'this' 函数对象与其他对象的处理方式不同。

考虑以下代码:

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

因为在对象 ('object') 上调用了函数 ('logMyName'),所以 'this' 设置为对象 ('object'),函数 ( 'logMyName') 被调用。

现在考虑以下代码:

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

尽管在对象 ('funcObject') 上调用了函数 ('logMyName'),但 'this' 设置为对象 ( 'funcObject') 调用了函数 ('logMyName')。

为什么对象类型之间存在这种差异,为什么要rarely/never 讨论它?

那是因为函数有一个特殊的 name 属性.

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 }.

属性 不可写,因此您的赋值被忽略。

但是,由于它是可配置的,您可以重新定义它:

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

请注意,在 ES6 将其标准化为可配置之前,一些旧浏览器将其实现为不可配置,因此上面的代码可能无法正常工作。