我的理解是所有类本质上都是函数,所有实例本质上都是对象。但有些事让我感到困惑。
//Take this for example:
function AnimalFunc(name) {
this.name = name;
this.sayName = function() {
console.log(this.name);
}
}
//And compare it with this:
class AnimalClass {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
//Now I instantiate them.
cat = new AnimalFunc("cat")
cat.sayName() // -> "cat"
dog = new AnimalClass("dog")
dog.sayName() // -> "dog"
console.log(Object.keys(cat));
console.log(Object.keys(dog));

预期观察结果:
typeof(AnimalClass)
和typeof(AnimalFunc)
都返回function
。typeof(cat)
和typeof(dog)
都返回object
。意外观察:
Object.keys(cat)
,我会["name","sayname"]
。Object.keys(dog)
,我会["name"]
。我的问题是:为什么我不将sayname
作为类实例的键?为什么我只为函数实例获取它?
答案 0 :(得分:4)
第一个带有函数的示例在创建实例时创建一个新的函数属性,因此,Object.keys
可以获取一个新的键。
第二个示例,带有一个类,将函数属性赋给对象prototype
。因此,实际上并未创建新密钥,并且可以通过走原型链找到sayName
函数。
您可以通过执行以下操作来复制类行为:
function AnimalFunc(name) {
this.name = name
}
AnimalFunc.prototype.sayName = function () {
console.log(this.name)
}
Here's some reading if you want to familiarize yourself with JS's prototype model.如果您愿意,可以通过搜索" javascript原型"来查找更多文章等。
答案 1 :(得分:3)
因为您已声明了两个名为sayname
和this.name;
this.sayname;
AnimalClass
在类name
中,您只将构造函数体中的键this.name = ....
声明为属性:
this
Object.keys()返回一个数组,其元素是与直接在对象上找到的可枚举属性相对应的字符串。属性的顺序与通过手动循环对象的属性给出的顺序相同。
因此,基本上将返回使用上下文class AnimalClass {
constructor(name) {
this.name = name;
// This is just to illustrate!
this.sayName = function() {
console.log(this.name);
}
}
}
console.log(Object.keys(new AnimalClass('Dog')))
直接声明的属性。
{{1}}
答案 2 :(得分:1)
这是因为 AnimalClass ' s sayName
位于 AnimalClass 的原型中,而 AnimalFunc < / strong>&#39; s this
不是,它是实例的一部分(sayName
)。
对于 AnimalClass ,只有一个class AnimalClass {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
var a = new AnimalClass("a"), b = new AnimalClass("b");
a.sayName === b.sayName; // true
函数,所有实例共享对以下内容的引用:
sayName
&#13;
每个 AnimalFunc 实例都有自己的function AnimalFunc(name) {
this.name = name;
this.sayname = function() {
console.log(this.name);
}
}
var a = new AnimalFunc("a"), b = new AnimalFunc("b");
a.sayName === b.sayName; // false
定义,因为它在构造函数中为每个实例重新定义:
function
&#13;
使用function AnimalFunc(name) {
this.name = name;
}
AnimalFunc.prototype.sayname = function() {
console.log(this.name);
}
的 AnimalClass 的等效是:
class
使用class AnimalClass {
constructor(name) {
this.name = name;
this.sayName = function() {
console.log(this.name);
}
}
}
的 AnimalFunc 相当于:
mix phoenix.server