当我打印对象时,我没有得到常规样式函数,而只得到了箭头样式函数。常规函数是隐藏在创建的对象中还是不属于类对象?
class Person {
pName = "Hasnain";
pAge = 22;
displayNormalFunc1()
{
return this;
}
displayNormalFunc2()
{
return this;
}
displayArrowFunc1 = ()=>
{
return this;
}
displayArrowFunc2 = ()=>
{
return this;
}
}
objp = new Person();
console.log(objp)
2条答案
按热度按时间nhhxz33t1#
displayArrowFunc1
、displayArrowFunc2
类似于变量,它将在每次初始化Person
时被初始化displayNormalFunc1
、displayNormalFunc2
是属于prototype
的方法,prototype
是原型编程语言的设计原则 它们仅在声明Person
时创建一次,并直接写入Person.prototype
。可以通过某些javscript API访问它们,但不在此问题中更多信息:
参见示例:
以及
fnatzsnv2#
这实际上与函数是否为箭头函数无关,我可以用同样的方式定义
displayArrowFunc
属性,但将其定义为“正则”函数表达式来重写示例,结果是相同的:结果实际上归结为关于Javascript对象和“类”的一些不同的东西。我将尽量不太深入,而是给予一个关键事实的快速总结,并附有链接。
Javascript有a version of "inheritance" for objects--直接用于对象,* 而不是 *“类”--这与Java和C#等语言中的a version of "inheritance" for objects大不相同。基本上,每个对象都链接到一个“原型对象”,用于查找原始对象上不存在的属性(包括函数属性或“方法”)。
当你
console.log
一个对象时,你只会看到“直接存在”于该对象上的属性--而不是那些存在于其原型或其原型的原型等等上的属性,尽管访问原型链中的属性仍然有效。这就是您所观察到的根本原因-原来原始示例中的“箭头样式函数”(以及我修改后的示例中的非箭头函数)是类示例
objp
的直接属性,但其他函数不是。“普通函数”并不是因为这就是Javascript“类”的工作方式。正如我试图通过使用引号来暗示的那样,JS实际上并没有“类”--它们是普通Javascript函数的语法糖。JS的特点是可以使用new operator调用任何函数,然后new operator将构造一个新对象。无论函数体本身实际上做什么。在ES6引入
class
关键字之前(大约在2014/5年),这曾经是人们在JS中使用“类”的方式。而向这样的“类”添加“方法”的方法应该是这样的:
注意这个方法实际上是对象
SomeClass.prototype
的一个属性--然后(由于JS内部的工作方式)它就变成了你通过const someInstance = new SomeClass(2);
构造的任何示例的“原型对象”(在上面提到的意义上)。这就是你的“类”代码被转换成的东西--它只是一个语法糖,这就是为什么
displayNormalFunc
等不被记录的原因--它们不在实际的示例对象上,而是在它的原型上。至于为什么
displayArrowFunc1
和朋友会被记录,那是因为你在类中用不同的方式定义了它们--这种方式是比“类”本身更新的JS特性。你把someProperty = something
放在类体中的地方,它们被称为class fields。注意我链接到的文档中的这句话:公共示例字段存在于类的每个创建的示例上。
简而言之,这就是为什么要记录它们--因为它们在示例上,而不是在其proortype上。这不仅适用于像
pName
和pAge
这样的“常规”值,还有你用这种方式定义的函数/方法--函数在Javascript中只是和其他值一样的值。这与您是否将这些函数表达式定义为箭头函数无关,而是您用来将它们添加到类中的语法。简而言之,类体中的
someProperty = someValue
将属性直接放在每个构造的示例上,包括someValue
是函数时。而“标准”方法定义是一种特殊的语法,它们最终被添加到所有此类示例的原型中-因此,当示例被记录时,它们不会出现。