当前位置: 首页 > Web前端 > CSS

《深入理解ES6》Note——JavaScript中的Class类(9)

时间:2023-03-30 22:24:45 CSS

ES5及之前版本的close-class结构,没有类的概念,但是聪明的JavaScript开发者创造了特殊的面向对象的类似结构。ES5中创建类的方法:创建一个新的构造函数,定义一个方法并将其赋值给构造函数的原型。'usestrict';//新建一个构造函数,默认以大写字母开头functionPerson(name){this.name=name;}//定义一个方法,赋值给构造函数的原型.sayName=function(){returnthis.name;};varp=newPerson('eryue');console.log(p.sayName()//eryue);ES6类ES6实现类很简单,只需要类声明。推荐babelonlinetestES6测试以下代码。类声明如果你学过java,你会非常熟悉这种声明类的方式。classPerson{//新建构造函数constructor(name){this.name=name//privateproperty}//定义一个方法,赋值给构造函数的原型sayName(){returnthis.name}}letp=newPerson('eryue')console.log(p.sayName())//eryue和ES5中使用构造函数的区别在于,在ES6中,我们将原型的实现写在类中,但本质还是一样的,需要新建一个类名,然后实现构造函数,再实现原型方法。私有属性:要在类中实现私有属性,只需要在构造函数中定义this.xx=xx即可。类声明和函数声明的区别和特点1、函数声明可以提升,类声明不能提升。2.类声明中的代码自动强制运行在严格模式下。3.类中的所有方法都是不可枚举的,在自定义类型中,可以通过Object.defineProperty()手动指定不可枚举的属性。4.每个类都有一个[[construct]]方法。5.只能用new来调用类的构造函数。6、类中不能修改类名。类表达式类有两种表现形式:声明式和表达式式。//declarativeclassB{constructor(){}}//匿名表达式letA=class{constructor(){}}//命名表达式,B可以在外部使用,而B1只能在内部使用letB=classB1{constructor(){}}类是一等公民JavaScript函数是一等公民,类也被设计成一等公民。1.可以将类作为参数传递给函数。//新建一个类letA=class{sayName(){return'eryue'}}//这个函数返回一个类的实例functiontest(classA){returnnewclassA()}//将alett引入到testfunction=test(A)console.log(t.sayName())//eryue2.可以通过立即调用类构造函数来创建单例。leta=newclass{constructor(name){this.name=name}sayName(){returnthis.name}}('eryue')console.log(a.sayName())//eryue访问器属性类支持定义原型上的访问器属性。classA{constructor(state){this.state=state}//创建gettergetmyName(){returnthis.state.name}//创建settersetmyName(name){this.state.name=name}}//获取指定对象自身的属性描述符。自属性描述符是直接在对象上定义的(而不是从对象的原型继承的)。letdesriptor=Object.getOwnPropertyDescriptor(A.prototype,"myName")console.log("get"indesriptor)//trueconsole.log(desriptor.enumerable)//false不可枚举的可计算成员名可计算成员指的是Usesquare括号包裹一个表达式,如下定义一个变量m,然后用[m]将其设置为类A的原型方法letm="sayName"classA{constructor(name){this.name=name}[m](){returnthis.name}}leta=newA("eryue")console.log(a.sayName())//eryuegeneratormethod回顾上一章提??到的generator,a生成器是一个返回迭代器的函数。在类中,我们也可以使用生成器方法。A类{*printId(){yield1;产量2;产量3;}}leta=newA()console.log(a.printId().next())//{done:false,value:1}console.log(a.printId().next())//{done:false,value:2}console.log(a.printId().next())//{done:false,value:3}这种写法很有意思,我们加一个原型方法改一下一点点。A类{*printId(){yield1;产量2;产量3;}render(){//从render方法中访问printId,你应该很熟悉,这是react中经常使用的写法。returnthis.printId()}}leta=newA()console.log(a.render().next())//{done:false,value:1}staticmember静态成员指的是方法名或者static关键字添加在属性名称的前面。与普通方法不同,静态修饰的方法不能在实例中访问,只能在类中直接访问。classA{constructor(name){this.name=name}staticcreate(name){returnnewA(name)}}leta=A.create("eryue")console.log(a.name)//eryuelett=newA()console.log(t.create("eryue"))//t.create不是一个函数继承和派生类我们在写react的时候,自定义组件会继承React.Component。classAextendsComponent{constructor(props){super(props)}}A称为派生类。在派生类中,如果使用构造函数,则必须使用super()。classComponent{constructor([a,b]=props){this.a=athis.b=b}add(){returnthis.a+this.b}}classTextendsComponent{constructor(props){super(props)}}lett=newT([2,3])console.log(t.add())//5使用super的要求:1.super只能在派生类中使用。派生类是从另一个类继承的新类。2.在构造函数中访问this之前调用super(),它负责初始化this。classTextendsComponent{constructor(props){this.name=1//报错,必须先写super()super(props)}}3.如果不想调用super,可以让constructorof该类返回一个对象。类方法遮蔽我们可以在继承类中重写父类的方法。classComponent{constructor([a,b]=props){this.a=athis.b=b}//父类add方法,sumadd(){returnthis.a+this.b}}classTextendsComponent{constructor(props){super(props)}//重写add方法并计算乘积add(){returnthis.a*this.b}}lett=newT([2,3])console.log(t.add())//6静态成员从父类继承静态成员,也可以从派生类继承。静态成员继承只能通过派生类访问,不能通过派生类的实例访问。classComponent{constructor([a,b]=props){this.a=athis.b=b}staticprintSum([a,b]=props){returna+b}}classTextendsComponent{constructor(props){super(props)}}console.log(T.printSum([2,3]))//5个从表达式派生的类很容易理解,也就是说父类可以是一个表达式。内置对象的继承有些牛逼的人认为使用内置的Array不够酷,所以他们希望ECMA提供一种继承内置对象的方法,然后一帮高手在类中添加这个功能。classMyArrayextendsArray{}letcolors=newArray()colors[0]="1"console.log(colors)//[1]没接触过Symbol.species的用法,目前只知道内置对象该方法在类中使用。如果在类中调用this.constructor,使用Symbol.species允许派生类覆盖返回类型。在构造函数中使用new.targetnew.target通常表示当前构造函数名称。通常我们使用new.target来防止直接实例化基类,下面是这个例子的实现。classA{constructor(){//如果当前new.target是classA,则抛出异常if(new.target===A){thrownewError("errorhaha??")}}}leta=newA()console.log(a)//error哈哈总结一下,这一章只有一个知识点,就是类的使用。类的初始声明,以及派生类后续的继承都是很常用的写法,也有静态成员的用法。如果上面的例子还不够你练手的话,或许你应该找个react的基础demo,简单的用class来练练手。=>返回文章目录