ES6基础之Class基本语法

实例化
在JS中,生成实例对象的传统方法是通过构造函数,例如:

function Point(x,y){
    this.x=x;
    this.y=y;
}
Point.prototype.toString=function(){
    return this.x+'  '+this.y;
}

var p=new Point(1,2);
console.log( p.toString() );//1  2

而ES6则引入了类的概念,作为对象的模板,通过class关键字,可以定义类。
我们使用ES6的方法将上面的例子改写一下。

//定义类
class Point {
    constructor(x,y){
        this.x=x;
        this.y=y;
    }
    toString(){
        return this.x+'+'+this.y;
    }
}
var b=new Point(1,2);
console.log( b.toString() );//1 +  2

习惯于JS的同学,可能不太理解这种做法。其实本质上是一样的,只要你理解了JS中原型对象的原理。

从上面例子中,我们可以看到定义了一个Point的类,类里面有一个constructor的方法,这就是构造方法,而this关键字则代表实例对象,实例化的时候this指向实例对象。
Point类除了构造方法以外,还定义了一个toString方法,注意,定义类的时候,不需要加上function这个关键字,方法之间也不需要逗号分隔,加了会报错。

console.log(typeof Point);//function
Point===Point.prototype.constructor;//true

从上面代码中我们可以看出,实例化的时候本质都没有变,构造函数以及原型对象,只是换了种形式。使用的时候也是直接new构造函数,该传参的传参。
事实上,类的所有方法都是定义在类的prototype属性上。

let p1=new Point(1,2);
p1.constructor===Point.prototype.constructor;//true

上面代码中p1是Point的实例,p1.constructor方法就是Point类原型的方法,由于类的的方法动定义在prototype对象上,所以可以利用Object.assign方法给原型对象添加新方法。

Object.assign(Point.prototype,{
    toString(){},
    toValue(){}
});

注意,ES6中,类的内部所有定义的方法都是不可枚举的,而ES5中是可以枚举的。

constructor构造函数
constructor方法是类的默认方法,通过new命令生成实例对象时,自动调用该方法。一个类必须有constructor方法,如果没有显示定义,则会默认的添加一个空的构造函数,这在ES5中是一样的。
constructor方法默认返回实例对象,同时也可以指定返回另一个对象。

class Foo {
    constructor(){
       return Object.create(null);
        //返回一个新的null对象
    }
}

所以:

var b=new Foo();

console.log(b.constructor);//undfined
console.log(b instanceof Foo);//false

注:构造函数一定要new,不然会报错。

类的实例对象

与ES5一样,实例的属性除非显示定义在其本身(即显示定义在this对象上),否则都是定义在原型上(即定义在class上);

var point = new Point(2, 3);
console.log( point.toString()  )// (2, 3)
console.log( point.hasOwnProperty('x')   ) // true
console.log( point.hasOwnProperty('y')  )// true
console.log( point.hasOwnProperty('toString')  ) // false
console.log( point.__proto__.hasOwnProperty('toString')  )// true

注:谨慎使用实例的__proto__属性修改原型对象,原理同ES5一样,会导致同样继承与原型对象的实例发现变化。

不存在变量提升

new Foo();
class Foo{}

Foo类使用在前,定义在后,会报错。

但是:

{
    let Foo = class {};
    class Bar extends Foo {}
}

这个是可以的,因为在第一步已将一个类赋给一个变量Foo。
Class表达式
跟函数一样,类也可以使用表达式的形式定义

const MyClass=class Me{
    getClassName(){
        return Me.name;
    }
}


let lg=new MyClass();
console.log(  lg.getClassName() );//Me
console.log( Me.name );//报错

这个类的名字是MyClass而不是Me,Me只在Class内部代码中可用,指代当前类。
如果class内部没有用到的话,可用省略Me.

let MyClass=class{}

采用Class表达式,可用写出立即执行的Class

let person=new class{
    private name;
    constructor(name){
        this.name=name;
    }
    sayName(){
        console.log( this.name );
    }
}('张三');

person.sayName();//张三

上面代码中,person是一个立即执行的类的实例。可以参考ES5中匿名函数立即执行。

本文参考ES6标准入门

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值