为什么类和函数在Javascript中的行为不同?

为什么类和函数在Javascript中的行为不同?,javascript,ecmascript-6,Javascript,Ecmascript 6,我的理解是,所有类本质上都是函数,所有实例本质上都是对象。但有些事情让我困惑 //举个例子: 函数AnimalFunc(名称){ this.name=名称; this.sayName=函数(){ console.log(this.name); } } //并将其与此进行比较: 类动物纲{ 建造师(姓名){ this.name=名称; } sayName(){ console.log(this.name); } } //现在我实例化它们。 猫=新动物基金(“猫”) cat.sayName()/-

我的理解是,所有类本质上都是函数,所有实例本质上都是对象。但有些事情让我困惑

//举个例子:
函数AnimalFunc(名称){
this.name=名称;
this.sayName=函数(){
console.log(this.name);
}
}
//并将其与此进行比较:
类动物纲{
建造师(姓名){
this.name=名称;
}
sayName(){
console.log(this.name);
}
}
//现在我实例化它们。
猫=新动物基金(“猫”)
cat.sayName()/->“cat”
狗=新的动物类(“狗”)
dog.sayName()/->“dog”
console.log(Object.keys(cat));

console.log(Object.keys(dog))
第一个示例是一个函数,它在创建实例时创建了一个新的函数属性,因此为要拾取的
对象.keys创建了一个新键

第二个示例是一个类,它将函数属性指定给对象的
原型。因此,实际上不会创建新的密钥,而
sayName
函数将在原型链中找到

可以通过执行以下操作复制类行为:

function AnimalFunc(name) {
  this.name = name
}

AnimalFunc.prototype.sayName = function () {
  console.log(this.name)
}

如果您愿意,可以通过搜索“javascript原型”来查找更多文章等。

这是因为AnimalClass
sayName
AnimalClass的原型中,而AnimalFunc
sayName
不是,它是实例的一部分(

对于AnimalClass,只有一个
sayName
函数,所有实例都共享一个引用:

类动物类{
建造师(姓名){
this.name=名称;
}
sayName(){
console.log(this.name);
}
}
变量a=新的动物类(“a”),b=新的动物类(“b”);

a、 sayName==b.sayName;//true
,因为您声明了两个名为
name
sayname

this.name;
this.sayname;
在类
AnimalClass
中,您仅将构造函数体中的键
name
声明为属性:

this.name = ....
key()返回一个数组,其元素是与直接在对象上找到的可枚举属性对应的字符串。属性的顺序与手动循环对象属性的顺序相同

因此,基本上将返回使用上下文
this
直接声明的属性

课堂示范
  • 构造函数体中函数的声明
类动物类{
建造师(姓名){
this.name=名称;
//这只是为了说明!
this.sayName=函数(){
console.log(this.name);
}
}
}

console.log(Object.keys(新的AnimalClass('Dog'))
Object.keys
只返回自己的属性。将方法放在构造函数中而不是原型中的
上是错误的。有关使用原型和定义原型的
语法的构造函数的比较,请参阅