Javascript 函数定义是对象吗?

Javascript 函数定义是对象吗?,javascript,Javascript,假设我有一个对象和一个函数定义: var jane = { firstName: 'Jane', lastName: 'Smith', describe: function () { return 'Person named '+this.firstName+this.lastName }, }; function Car (desc) { this.desc = desc; this.color = "red"; thi

假设我有一个对象和一个函数定义:

var jane = {
    firstName: 'Jane',
    lastName: 'Smith',
    describe: function () {
        return 'Person named '+this.firstName+this.lastName
    },
};

function Car (desc) {
    this.desc = desc;
    this.color = "red";
    this.getInfo = function getInfo() {
        return 'A ' + this.color + ' ' + this.desc + '.';
    };
}
我可以枚举对象的键:值对,因此:

obj=jane
for (var prop in obj) {
  console.log(`obj.${prop} = ${obj[prop]}`);
}
但函数定义失败(函数表达式也是如此)

如果函数定义是一个对象,那么为什么我不能枚举它的属性呢?有办法吗


谢谢

在这种情况下
指的是全局对象
窗口
或严格模式下的
未定义
。 将其用作构造函数:
obj=new Car(desc)

当函数是对象时,
函数中此
特殊对象的属性不在函数本身的
for…in
循环中

如果您不喜欢在新对象上使用
this
运算符,使其属性在该新对象上可枚举,请使用如下显式
this
参数:

var obj = {};
Car.call(obj);
功能车(描述){
this.desc=desc;
this.color=“red”;
this.getInfo=函数getInfo(){
返回“A”+this.color+“”+this.desc+”;
};
}
var obj={};
汽车呼叫(obj);
用于(obj中的var prop){
log(`obj.${prop}=${obj[prop]}`);

}
让我们想象你站在一家汽车厂前面。你能预测下一辆车会离开吗?或者工厂关门了,什么也不退

import Car from "factory";
var car=new Car();//what will car be?
所以基本上你无法预测构造函数将构造什么。但如果汽车厂只生产柴油发动机,我们可以通过原型链来了解,例如:

new Car() instanceof Diesel;//true
new Car instanceof Car;//true => all cars have the same prototype ( Car.prototype)
因此,回到您的示例,如果属性是静态的,那么像这样使用继承是有意义的:

function Car (desc) {
this.desc = desc;//unpredictable
}
Car.prototype={
  color:"red",//predictable, every car inherits from this
  getInfo() {
    return 'A ' + this.color + ' ' + this.desc + '.';
  },
};
因此,为了获得静态属性,您可以迭代原型:

for(key in Car.prototype);//iterates over color and getInfo

函数定义是一个对象,这是正确的,但您试图实现的是迭代该函数内部声明为的某个对象,这是不可能的(想象一下尝试迭代函数的局部变量-似乎很愚蠢,而且您有一种类似的概念)。你可以随时尝试

obj = new Car("dummy");
它将迭代函数返回的对象。如果不调用
new
,就无法从外部访问这些属性



请注意,这些属性不是在函数对象上定义的属性。它们是该函数返回的对象的属性。因此JavaScript需要一些新的语法,因为使用一个简单的
for。。在
循环中,这将是一个突破性的变化。

汽车是一种东西,
新车
本身就是一种东西
this.desc
适用于对象本身。因此,您无法迭代某一类型的对象?@Eggy一般来说,您无法预测构造函数在使用给定参数调用实例时会向实例添加哪些属性<代码>函数Car(){this[Math.random()]=Math.random()}所以您需要先创建一个实例
var aCar=new Car('test')
然后才检查属性。@Eggy概念上有图灵完整性。您甚至无法预测它是否终止。:)此外,js函数甚至不需要是纯函数。继续解析
函数Car(){this[Math.random()]=Math.random()}
:)嗯,但也许你在找?是的,那么我就有一个对象。我在问我是否可以以某种方式迭代函数定义本身OK,好吧,如果做不到,就做不到:)谢谢你的选择。是的,我在另一个回复中提到了手动解析替代方法。@Eggy如果你给我10分钟,我将尝试解析源代码字符串,这将是一个有趣的练习。。。但我想我不会推荐我的简单版本的生产代码:D您可能想探索一些严肃的解析器,例如,看看Ok。玩得开心:)我问Q是因为我想从概念上理解函数/对象/属性的结合方式,因为我刚刚开始接触JavaScript:)我不明白为什么以这种方式查询函数定义是没有用的!好吧,你不能把构造函数和
this
一起使用,而是使用普通对象……是的,你的解析器产生了我想要的类型。做得好:)顺便说一句,re-plain object etc对其进行注释,以获取现有函数并询问它,而不是编写新函数/对象。有趣的是,原型是iterable的,但函数定义本身不是。@eggy函数也是iterable的。但是你想重复一些还不存在的东西(=>不可预测的=不可能的),谢谢你的回答。构造函数有什么选项并不重要,我们不需要预测实际值。我只想要键:值函数定义对。我们可以通过解析来实现。JavaScript似乎没有通过内部代码以这种方式公开它们methods@eggy为什么?简单地手动取出不是更容易吗?你想要的不是真正的值,而是键:值对???这是没有意义的,比如说,我想询问1000个函数定义中的重复键名。给定一个副本,我想测试默认值的差异。这不是我的密码。我无法调整它,甚至无法有意义地运行它。如果能在FD上迭代,那就太好了,不是吗?如果你说的是“代码”,我明白你的意思了。我不是。JavaScript是否能做到这一点(显然,解释器这样做是为了生成可运行的代码)并不意味着解析函数定义的键:值对不是合理的要求。请注意,这些属性不是函数对象上定义的属性。它们是该函数返回的对象的属性。因此JavaScript需要一些新的语法,因为使用一个简单的
for。。在
中,循环将是一个突破性的变化。但我同意你的观点,理论上是可以实施的。然而,在这个时候,这样的特征并不存在。我同意这一点,“但我同意你。”
obj = new Car("dummy");