为什么不能使用函数名称在 JavaScript 中检索属性

Why cannot use function name to retrieve property in JavaScript?

本文关键字:JavaScript 检索 属性 不能 函数 为什么      更新时间:2023-09-26

以下是代码

function add() {
  var counter = 0;
  this.num = 0;
  function plus (){ return counter +=1;}
  plus();
  return counter;
}
console.log(add.num); //outputs :undefined
函数

名称可以被视为函数对象的引用,因此 num 是添加函数对象的属性,输出可以是 0。但结果不是这样,为什么?

如果我将代码更改为:

function add() {
      var counter = 0;
      this.num = 0;
      function plus (){ return counter +=1;}
      plus();
      return counter;
    }
var obj = new add();
    console.log(obj.num); //outputs : 0

它工作正常。谁能解释一下?很多谢谢。

this是指函数的当前实例。 直到您使用new add()创建新实例,这将引用window对象。

add.num将检查add是否有名为 num 的属性。这是错误的,因为add指的是函数定义而不是函数的实例/对象。

function add() {
  var counter = 0;
  this.num = 0;
  function plus (){ return counter +=1;}
  plus();
  return counter;
}
console.log(add.num); //outputs :undefined  because add=function(){};

而在另一种情况下,当您使用 new 创建对象时,它会返回一个具有所有公共属性的 JavaScript 对象。

//

/obj=Object{ num : 0};

function add() {
      var counter = 0;
      this.num = 0;
      function plus (){ return counter +=1;}
      plus();
      return counter;
    }
var obj = new add();
    console.log(obj.num); //outputs : 0 because obj is {num:0}

小提琴演奏:http://jsfiddle.net/ZpVt9/76/

这将有助于

阅读JavaScript中的this: MDN

当你做new add()时,解释器会创建一个新的JavaScript对象/哈希,并将其绑定到函数中的this变量。因此this函数范围内是有效的。

当你不做一个new你就是在没有上下文的情况下调用函数,所以在这种情况下this是未定义的(在"使用严格"模式下)。

您可以使用 Function.apply/Function.call/Function.bind 将上下文显式传递给函数

函数内部的this指向不同的对象,具体取决于函数的调用方式:

  1. 如果在全局上下文(在任何函数外部)中调用函数,则this指向全局对象(如果脚本在浏览器中执行,则window全局对象)。 console.log(this === window)将输出 true。
  2. 如果在函数内部引用this,则取决于我们是否设置了严格模式。

    • 如果代码处于严格模式,那么除非我们明确地将其分配给某些东西,否则this将被undefined

    • 如果代码未处于严格模式,则this将指向全局对象。(如果在浏览器中执行脚本,则再次window)。

  3. 如果函数用作构造函数来创建新对象,则this指向正在创建的新对象。

  4. 如果函数用作对象方法,则调用指向对象方法this

更多解释和示例在这里: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this


每个函数都是 JavaScript 中的一个对象。但是,从上面的解释中可以看出,this没有一种方式指向来自同一函数体的函数对象本身。因此,设置函数属性的唯一方法是直接将其分配给函数,而无需使用 this

还有另一种向函数添加属性的方法。这样做是一个非常糟糕的主意,因为以这种方式添加任何属性都会反映在所使用的所有函数中。每个函数都链接到Function.prototype对象。因此,在此对象中添加任何属性都将反映在所有函数中。

Function.prototype.someProperty = 1;
//now try accessing it via any function object
console.log(add.someProperty); //should print 1 to console.

"num" 不是 "add" 函数的属性 是该函数创建和返回的对象的属性 如果你想将 num 添加到你的 add 函数中,你需要做

add.prototype.num=0; 

并将其从对象定义中删除