在javascript中,对象文字和构造函数中包含值的类之间有什么区别?
我一直在testcafe中进行端到端测试,在他们的文档中,我发现了页面模型的以下解决方案:在javascript中,对象文字和构造函数中包含值的类之间有什么区别?,javascript,class,object,constructor,Javascript,Class,Object,Constructor,我一直在testcafe中进行端到端测试,在他们的文档中,我发现了页面模型的以下解决方案: class Page { constructor () { this.nameInput = Selector('#developer-name'); } } export default new Page(); 我一直在做一些研究,但我无法理解为什么不能用对象文字来解决这个问题: export const Page = { nameInput: Selecto
class Page {
constructor () {
this.nameInput = Selector('#developer-name');
}
}
export default new Page();
我一直在做一些研究,但我无法理解为什么不能用对象文字来解决这个问题:
export const Page = {
nameInput: Selector('#developer-name');
}
使用它们的后果是什么?类可以看作是一个蓝图,它们最终都提供了一个对象。但是,正如对象文字名称所暗示的,您可以直接在那里创建它,然后使用这种“文字”语法。然而,我们将使用一个类来实例化1个基本蓝图中的新实例
let x = { myProp: undefined }
let y = { myProp: undefined }
x.myProp = "test";
y.myProp // undefined
在这里,我们创建了两个单独的实例,但我们必须重复代码
class X { }
let x = new X();
let y = new X();
类不需要重复代码,因为它都封装在X应该是什么的概念中,即蓝图
let x = { myProp: undefined }
let y = { myProp: undefined }
x.myProp = "test";
y.myProp // undefined
与上面[字面上]类似,我们有两个单独的实例,但它更干净、可读性更强,我们希望对这个“X”对象的每个实例所做的任何更改现在都可以在类中简单地更改
还有很多其他好处,甚至还有一个专门用于面向对象编程的范例,请阅读此处了解更多信息:
要进一步探讨构造函数问题。。。在其他语言中,我们有字段。
我相信当你在构造器中分配一个字段时,它只会创建一个类似于underthehood的字段(我说underthehood-like是因为JavaScript是基于原型的,而类语法是语法糖,可以帮助熟悉其他语言中类语法的程序员更容易地编写原型)
下面是C#中的一个例子
在其他语言中,在构造函数中分配字段更像是一种约定,因此我假设这与JavaScript中的字段分配有关
希望这会有所帮助。通过将其声明为类,您可以在以后识别它所使用的对象类型。constructor.name:
类页面{
构造函数(){
this.nameInput=“something”;
}
//没有逗号
anotherMethod(){
}
}
const pageClass=新页面();
常量pageLiteral={
名称输入:“某物”
,//必须有逗号
anotherMethod(){
}
}
console.log(“类的构造函数名称:”,pageClass.constructor.Name);//页
console.log(“literal的构造函数名称:”,pageLiteral.constructor.Name);//对象
差别很大,但基本上两者都是JavaScript对象,尽管属性和值不同。列出语言层面上的所有差异将是一个很长的故事,你应该明智地继续阅读和理解,但最重要的差异是:
是一个原型对象:每当使用Page
创建类new Page()
的对象时,构造函数将使用Page
调用,它引用的是正在创建的对象,而不是this
本身。您在对象上访问的任何属性都将沿着所谓的“原型链”进行搜索,包括所谓的原型对象。可以通过Page
实际上,您在类页面访问此原型对象。prototype
中定义的所有方法也是此原型对象的属性。与自己的属性不同,JavaScript中的函数被设计为引用特定于对象的唯一对象或原语,在对象或函数创建期间不必绑定到对象,可以在对象之间共享(例如,属于同一类),并在实际实例上调用,而不是它们可能属于的原型。换句话说,构造函数中的页面
实际上向使用this.nameInput
创建的对象添加了名为new Page()
的属性,而不是原型,而构造函数本身(nameInput
)您可能添加到构造函数
的任何非静态方法都将作为Page
的属性添加。顺便说一句,正如您自然期望的那样,可以通过Page.prototype
访问构造函数<代码>Page.prototype.constructor==Page计算结果为Page.prototype.constructor
true
- 类似于
的形式表达式创建了一个原型为{nameInput:…}
对象的对象。原型实际上是对象的最基本形式,没有原型,因此没有超类或超出基本对象原型对象所能提供的任何特征。任何这样的
对象似乎通过其原型链拥有的任何属性,包括方法,都是{…}
。这就是为什么您可以执行对象的属性。原型
或({}).toString()
对象中实际上没有({}).hasOwnProperty(“foobar”)
或toString
属性--hasOwnProperty
和toString
是hasOwnProperty
引用了两种不同的方法,分别称为对象的属性。prototype
和toString
,JavaScript在对象上创建一个名为hasOwnProperty
的特殊属性,该属性引用\uuuuu proto\uuuu
。这就是它知道如何“走原型链”的方式。顺便说一句,函数本身的名称并不重要——我可以在引用匿名函数的对象上添加一个属性:object.prototype
并使用var foo=({});foo.bar=函数(){}
调用所述未命名函数foo.bar()
export default class Page{…}
与export const Page={nameInput:Selector(…)}
——前者创建一个可作为页面
访问的类,该类在创建类的对象时用作原型对象,而后者创建一个可作为页面
访问的对象,该页面包含名称输入
引用r
new (function() { this.nameInput = Selector("#developer-name"); })();
function Page() {
this.nameInput = Selector("#developer-name");
}
var foo = new Page();
function Page() {
this.nameInput = Selector("#developer-name");
}
Page.prototype.bar = function() {
console.log(this.nameInput);
}
var foo = new Page();
foo.bar();
class Page {
constructor() {
this.nameInput = Selector("#developer-name");
}
bar() {
console.log(this.nameInput);
}
}