ES6 的类提供了几点明显的好处:
兼容当前大量的代码。
相对于构造器和构造器继承,类使初学者更容易入门。
子类化在语言层面支持。
可以子类化内置的构造器。
不再需要继承库;框架之间的代码变得更加轻便。
为将来的高级特性奠定了基础: traits (或者 mixins ), 不可变实例,等等。
使工具能够静态分析代码( IDE ,类型检测器,代码风格检测器,等等)。
ES6 类掩盖了 JavaScript 继承的本质;
类会禁锢你,因为强制性的 new。
主要缺点是,比较复杂,用到了this和prototype,编写和阅读都很费力。
上面的式子可以如下简单的理解:
上面代码的改用class来写
class Points { constructor(x, y) { this.x = x; this.y = y; } toString(){ return '(' + this.x + ',' + this.y + ')'; } } const ps = new Points(1, 2); console.log(ps);//Points {x: 1, y: 2} console.log(ps.toString());//(1,2)ES6的类可以看作构造函数的另一种写法
class Cty{ //.... } console.log(typeof Cty);//function console.log(Cty === Cty.prototype.constructor);//true //类的数据类型是函数,类本身就指向构造函数上面可以理解为:类的数据类型是函数,类本身就指向构造函数
使用的时候,也是直接对类使用new命令,跟构造函数的用法完全一致
class Bar { doStuff(){ console.log('stuff'); } } const b =new Bar(); b.doStuff();//stuff类的实例上面的方法,其实就是调用原型上的方法
class B {}; const BS = new B(); console.log(BS.constructor === B.prototype.constructor);//true 类与子类 class Poin{ constructor(x,y){ this.x = x; this.y = y; } toString(){ return `(${this.x},${this.y})`; } } class ColorPoin extends Poin{ constructor(x,y,color){ super(x,y); this.color = color; } toString(){ return super.toString() + " in " + this. color; } } // 类型 console.log(typeof Poin);//function //news实例 const cp = new ColorPoin(25,8,'green'); console.log(cp.toString());//(25,8) in green console.log(cp instanceof ColorPoin);//true console.log(cp instanceof Poin);//true // instanceof测试构造函数的prototype属性是否出现在对象的原型链中的任何位置Javascript还提供了一个instanceof运算符,验证原型对象与实例对象之间的关系(instanceof测试构造函数的prototype属性是否出现在对象的原型链中的任何位置)。
下面是一些方法:
Object.assign方法可以很方便的一次像类添加多个方法 class ObjAssign { constructor(name, age){ this.name = name; this.age = age; } } Object.assign(ObjAssign.prototype,{ toString(){ console.log("string"); }, toValue(){ console.log("value") } }) const Obj = new ObjAssign('Bob',24); console.log(Obj); Obj.toString();//string Obj.toValue();//value console.log(Object.keys(ObjAssign.prototype));//["toString", "toValue"] console.log(Object.getOwnPropertyNames(ObjAssign.prototype));// ["constructor", "toString", "toValue"] 类的实例 class Pott { constructor(x,y){ this.x = x; this.y = y; } toString() { return '(' + this.x + ',' + this.y + ')'; } } const pott = new Pott(2,3); pott.toString(); console.log(pott.hasOwnProperty("x"));//true console.log(pott.hasOwnProperty("y"));//true console.log(pott.hasOwnProperty("toString"));//false console.log(pott); console.log(pott.__proto__); console.log(pott.__proto__.hasOwnProperty("toString"));//true const p1 = new Pott(2,3); const p2 = new Pott(3,3); console.log(p1.__proto__ === p2.__proto__);//true p1.__proto__.printName = function(){ return "Oops"; } console.log(p1.printName());//Oops console.log(p2.printName());//Oops const p3 = new Pott(4,2); console.log(p3.printName());//Oops 取值函数(getter)和存值函数(setter)prop属性有对应的存值函数和取值函数
class MyClass { constructor(){ //... } get prop(){ return 'getter'; } set prop(value){ console.log("setter:" + value); } } const inst = new MyClass(); inst.prop = 123;//setter: 123 console.log(inst.prop)//getter 存值函数和取值函数是设置在属性的Descriptor对象上的 class CustomHTMLElement { constructor(element) { this.element = element; } get html() { return this.element.innerHTML; } set html(value) { this.element.innerHTML = value; } } const descriptor = Object.getOwnPropertyDescriptor( CustomHTMLElement.prototype, "html" ); console.log("get" in descriptor) // true console.log("set" in descriptor) // true calss 表达式 const MyCl = class Me { getClassName() { return Me.name; } } const inMe = new MyCl(); console.log(inMe.getClassName());//Me 只在class内部有定义 person立即执行实例 const person = new class{ constructor(name){ this.name = name; } sayName(){ console.log(this.name); } }('张三'); person.sayName();//张三 class name 属性 class Mine { //... } console.log(Mine.name);//Mine class this的指向问题