深入理解ES6之类
2018-03-09 本文已影响0人
IDO0
一:类与自定义类型的区别:
1:类生命不会被提升,这与函数定义不同。类声明的行为与let相似,因此在程序的执行到达声明之前,类会存在暂时性死区。
2:类声明的所有代码会自动运行在严格模式下
3:类的所有方法都是不可枚举的,自定义类型必须用Object.defineProperty()才能将方法改变为不可枚举。
4:累的所有方法内部都没有[[construct]],因此使用new来调用他们会抛出错误
5:调用类构造器时不使用new,会抛出错误。
6:试图在类的内部重写类名会抛出错误。
二:类声明与表达式
1:声明:
class Person{
constructor(){
}
sayName(){
}
}
let person = new Person();
console.log(person instanceof Person); //true
console.log(person instanceof Object); //true
console.log(typeof Person); //"function"
console.log(typeof Person.prototype.sayName)//"function"
1:表达式:
表达式被设计用于变量声明,或可作为参数传递给函数。
let Person = class PersonT{
constructor(){
}
sayName(){
}
}
console.log(typeof Person); //"function"
console.log(typeof PersonT) //"undefined"
等价于
let Person = (function(){
"use strict";
const PersonT = function(){
if(typeof new,target === "undefined"){
throw new Error("constructor must be called with new");
}
}
Object.defineProperty(PersonT.prototype,"sayName",{
value:function(){
if(typeof new.target!=="undefined"){
throw new Error("Method cannot be called with new.")
}
}
});
return PersonT;
}())
对类声明来说,外部绑定与内部绑定有着相同的名称。而类表达式可在内部使用const来定义它的不同名称,因此PersonT只能在类的内部使用。
三:类属性方法
1:类中也可以使用变量来声明方法:
let methodName = "sayName";
class Person{
constructor(name){
this.name=name;
}
[methodName](){
return this.name;
}
}
let me = new Person("wuyunqiang");
me.sayName();//"wuyunqiang"
2:静态成员:
//ES6之前
function Person(name){
this.name = name;
}
//静态方法
Person.create = function(name){
return new Person(name);
}
//实例方法
Person.prototype.sayName = function(){
console.log(this.name);
};
let person = Person.create("wyq");
//ES6
class Person{
//等价Person构造器
construtor(name){
this.name = name;
}
//等价Person.prototype.sayName
sayName(){
console.log(this.name);
}
//等价Person.create
static create(name){
return new Person("wyq");
}
}
三:类继承
1:屏蔽父类方法:
2:继承静态成员:
如果基类包含静态成员,那么这些静态成员在派生类中也是可用的。
3:从表达式中派生类:
并不是所有表达式的结果都是有效的,例如下面。
1:null
2:生成器函数
在ES6中派生类的最强大能力,或许就是能够从表达式中派生类。只要一个表达式能够返回一个具有[[construct]]属性以及原型的函数,就可以对其使用。
let SerializableMixin = {
serialize(){
return JSON.stringify(this);
}
}
let AreaMixin = {
getArea(){
return this.length*this.width;
}
}
function mixin(...mixins){
var base = function(){}
Object.assign(base.prototype,...mixins);
return base;
}
class Square extends mixin(AreaMixin, SerializableMixin){
constructor(length){
super();
this.length = length;
this.width = length
}
}
var x = new Square(3);
console.log(x.getArea());// 9
console.log(x. serialize());//"{lenght:3,width:3}"
4:从内置对象中派生类:
四:关于super和new.target
1:super只能在派生类中使用
2:new.target属性在constructor内部始终有值,不会存在undefined情况。可以使用new.target创建一个抽象基类,自能通过子类继承实例化.
class Person{
constructor(){
if(new.target===Person){
throw new Error("This class cannot be instantiated directly.");
}
}
}