在面向对象编程中,类是用于创建对象的可扩展程序代码模板,它为对象(成员函数或方法)提供状态(成员变量)的初始值和行为).在维基百科的日常开发中,我们经常需要创建很多同类型的对象,比如users(用户)、goods(商品)或者其他任何东西。正如我们在构造函数和操作符“new”一章中已经了解到的,new函数可以帮助我们实现这个需求。但在现代JavaScript中,还有一种更高级的“类”构造,它引入了许多很酷的新特性,对面向对象编程很有用。1、“类”语法基本语法为:classMyClass{//类方法constructor(){...}method1(){...}method2(){...}method3(){...}。..}然后使用newMyClass()使用上面列出的所有方法创建一个新对象。new会自动调用constructor()方法,所以我们可以在constructor()中初始化对象。例如:classUser{constructor(name){this.name=name;}sayHi(){alert(this.name);}}//用法:letuser=newUser("John");user.sayHi();当调用newUser("John")时:创建一个新对象。构造函数使用给定的参数运行并为其分配this.name。...然后我们可以调用对象方法,例如user.sayHi。类的方法之间没有逗号新手开发人员的一个常见陷阱是在类的方法之间放置逗号,这会导致语法错误。不要将此处的符号与对象文字混淆。在一个类中,不需要逗号。二、什么是类?那么,究竟什么是类?正如人们可能认为的那样,这不是一个全新的语言级实体。让我们揭开它的神秘面纱,看看类到底是什么。这将帮助我们理解许多复杂的方面。在JavaScript中,类是一种函数。看看下面的代码:classUser{constructor(name){this.name=name;}sayHi(){alert(this.name);}}//证据:User是一个函数alert(typeofUser);//functionclassUser{...}构造实际上执行以下操作:创建一个名为User的函数,该函数成为类声明的结果。这个函数的代码来自构造方法(不写就假定为空)。存储类中的方法,比如User.prototype中的sayHi。当创建了新的User对象,当我们调用它的方法时,它会从原型中获取对应的方法,我们在F.prototype章节中说过。因此,对象newUser可以访问类中的方法。我们可以将类User声明的结果解释为:这些代码很好地解释了它们:classUser{constructor(name){this.name=name;}sayHi(){alert(this.name);}}//类是一个functionalert(typeofUser);//function//...或者,更准确地说,构造方法alert(User===User.prototype.constructor);//true//方法在User.prototype中,例如:alert(User.prototype.sayHi);//alert(this.name);//原型中其实有两个方法alert(Object.getOwnPropertyNames(User.prototype));//constructor,sayHi3.不仅仅是语法sugar人们常说class是一种语法糖(语法设计是为了让内容更容易阅读,但不引入任何新东西),因为我们实际上可以在没有class的情况下声明相同的内容://用纯函数重写classUser//1。创建一个构造函数functionUser(name){this.name=name;}//函数的原型(prototype)默认有一个“constructor”属性,//所以,我们不需要创建它//2.在原型中添加方法User.prototype.sayHi=function(){alert(this.name);};//用法:letuser=newUser("John");user.sayHi();这个定义的结果和使用类基本一样。所以这确实是将类视为一种用于定义构造函数及其原型方法的语法糖的原因。但是有一些重要的区别:首先,通过类创建的函数有一个特殊的内部属性符号[[FunctionKind]]:"classConstructor"。所以它与手动创建它并不完全相同。编程语言会在很多地方检查这个属性。例如,与普通函数不同,它必须使用new调用:classUser{constructor(){}}alert(typeofUser);//函数用户();//错误:如果没有'new',则无法调用类构造函数User此外,在大多数JavaScript引擎中,类构造函数的字符串表示形式以“class...”开头//classUser{...}和其他的区别,我们很快就会看到。类方法不可枚举。类定义将“原型”中所有方法的可枚举标志设置为false。这很好,因为如果我们在一个对象上调用for..in,我们通常不希望类方法出现。类总是使用usestrict。类构造函数中的所有代码都会自动进入严格模式。此外,类语法带来了许多其他特性,我们将在后面探讨。第四,类表达式就像一个函数,一个类可以在另一个表达式中定义、传递、返回、赋值等。下面是类表达式的示例:letUser=class{sayHi(){alert("Hello");}};与命名函数表达式类似,类表达式也应该有一个名称。如果类表达式有名称,则该名称仅在类内部可见://"NamedClassExpression"//(规范中没有这样的术语,但它类似于命名函数表达式)letUser=classMyClass{sayHi(){alert(MyClass);//名字MyClass只在类内部可见}};newUser().sayHi();//正常运行,显示MyClass中定义的内容alert(MyClass);//错误,MyClass从外部是不可见的我们甚至可以“按需”动态创建类,像这样:functionmakeClass(phrase){//声明一个类并返回它returnclass{sayHi(){alert(phrase);}};}//CreateanewclassletUser=makeClass("Hello");newUser().sayHi();//Hello五、Getters/setters类似于对象字面量,类可能包括getters/setters、计算属性等。下面是一个用get/set实现user.name的例子:classUser{constructor(name){//callsetterthis.name=name;}getname(){returnthis._name;}setname(value){if(value.length<4){alert("Nameistooshort.");return;}this._name=value;}}letuser=newUser("John");alert(user.name);//Johnuser=newUser("");//名字太短。从技术上讲,这样的类声明可以通过在User.prototype中创建getter和setter来实现。6.计算属性名[…]下面是一个使用方括号计算方法名的例子[...]:classUser{['say'+'Hi'](){alert("Hello");}}newUser()。打招呼();这些特征很容易记住,因为它们类似于对象字面量。七、Classfield旧的浏览器可能需要polyfillclassfield(字段)是最近才被添加到语言中的。以前,我们班只有方法。“类字段”是一种允许添加任何属性的语法。例如,让我们为类User添加一个名称属性:classUser{name="John";sayHi(){alert(`Hello,${this.name}!`);}}newUser().sayHi();//你好约翰!所以,我们只要在表达式中写上“=”,就可以了。与类字段的重要区别在于它们是在每个单独的对象中设置的,而不是在User.prototype中:prototype.name);//undefined我们也可以在赋值时使用更复杂的表达式和函数调用:classUser{name=prompt("Name,please?","John");}letuser=newUser();alert(user.name);//John8.使用类字段来制作绑定方法函数绑定一章提到过,JavaScript中的函数有一个动态的this。这取决于调用上下文。因此,如果某个对象方法在某处传递,或在另一个上下文中调用,则this将不再是对其对象的引用。例如,这段代码将显示未定义:classButton{constructor(value){this.value=value;}click(){alert(this.value);}}letbutton=newButton("hello");setTimeout(button.click,1000);//undefined这个问题叫做“丢这个”。正如我们在函数绑定一章所说,有两种方法可以修复它:传递一个包装函数,例如setTimeout(()=>button.click(),1000)。将方法绑定到对象,例如在构造函数中。类字段提供了另一种非常优雅的语法:classButton{constructor(value){this.value=value;}click=()=>{alert(this.value);}}letbutton=newButton("hello");setTimeout(button.click,1000);//hello类字段click=()=>{...}是基于每个对象创建的,这里每个Button对象都有一个独立的方法,在内部有一个this指向这个对象.我们可以在任何地方传递button.click,这将始终具有正确的值。在浏览器环境中,它对于事件监听特别有用。九。总结基本的类语法如下所示:classMyClass{prop=value;//propertyconstructor(...){//constructor//...}method(...){}//methodgetsomething(...){}//getter方法setsomething(...){}//setter方法[Symbol.iterator](){}//带有计算名称的方法(此处为符号)//。..}从技术上讲,MyClass是一个函数(我们提供的构造函数),方法、getter和settor都写入MyClass.prototype。
