完整详细的es6 class

class基本声明

在说class之前,想必大家肯定会想到constructor function. 看下面代码:

function Foo(name) {
   
  this.name = name
}

class Bar {
   
  constructor(name){
   
    this.name = name
  }
}
f = new Foo('xhs')
b = new Bar('xhs')

两个差不多吧,foo function是在new的时候,把this指向当前的新创建的空对象,并且会把进行属性分配。bar class是在constructor里进行接收参数。

但是两个还是 有些不同

  • class声明并不像function声明,他不存在提升。他类似let声明,存在TDZ(temporal dead zone)
  • class中的代码都会自动的使用严格模式,没办法选择。
  • 所有的方法都是不可枚举的(non-enumerable), 注:非绑定当前对象的方法。
  • class内所有方法内部都缺少[[Construct]]方法,所以如果对这些方法进行new会出错。
  • 不携带new操作符调用class会报错。
  • 尝试在类的方法中改变类名会出错。

考虑到上面这几点,下面来看一个等价的例子:

class PersonClass {
   

    // equivalent of the PersonType constructor
    constructor(name) {
   
        this.name = name;
    }

    // equivalent of PersonType.prototype.sayName
    sayName() {
   
        console.log(this.name);
    }
}

上面的代码将等价下面无class的语法

// direct equivalent of PersonClass
let PersonType2 = (function() {
   

    "use strict";

    const PersonType2 = function(name) {
   

        // make sure the function was called with new
        if (typeof new.target === "undefined") {
   
            throw new Error("Constructor must be called with new.");
        }

        this.name = name;
    }

    Object.defineProperty(PersonType2.prototype, "sayName", {
   
        value: function() {
   

            // make sure the method wasn't called with new
            if (typeof new.target !== "undefined") {
   
                throw new Error("Method cannot be called with new.");
            }

            console.log(this.name);
        },
        enumerable: false,
        writable: true,
        configurable: true
    });

    return PersonType2;
}());

我们来分析上面这个无class语法的代码段。

首先注意到这里有两个PersonType2的声明(let声明在作用域外面,constIIFE里),这个就是禁止类方法覆盖类名。
在构造方法里有new.target来检测确保通过new调用,与之相对的是对方法的检测,排除new方法调用的可能,否则抛错。在下面就是enumerable: false,最后返回这个构造函数.
虽然上面的代码可以实现class的效果,但是明显,class更加简洁方便。

类的常量名称。

常量是不可被改变的,否则就会报错。类的名称只是在内部使用const,这就意味着在内部不可以改变名称,外面却可以。

class Foo {
   
   constructor() {
   
       Foo = "bar";    // 执行的时候报错。
   }
}

// 这里不会报错。
Foo = "baz";

class表达式

classfunction类似,也可以使用表达式。

let PersonClass = class {
   
    // equivalent of the FunctionName constructor
    constructor(name) {
   
        this.name = name;
    }
    // equivalent of FunctionName.prototype.sayName
    sayName() {
   
        console.log(this.name);
    }
};

可以发现,表达式语法类似,使用class的表达式还是声明都只是风格的不同,不像构造函数的声明和表达式有着提升的区别。

当然,上面的表达式是一个匿名表达式,我们可以创建一个携带名称的表达式。

let PersonClass = class PersonClass2 {
   
    constructor(name) {
   
        this.name = name;
    }
    sayName() {
   
        console.log(this.name);
    }
};
console.log(typeof PersonClass);        // "function"
console.log(typeof PersonClass2);  // undefined

可以发现上面输出PersonClass2是未定义,因为他只有存在类定义中, 如需了解,我们做下面的一个转变:

// direct equivalent of PersonClass named class expression
let PersonClass = (function() {
   

    "use strict";

    const PersonClass2 = function(name) {
   

        // make sure the function was called with new
        if (typeof new.target === "undefined") {
   
            throw new Error("Constructor must be called with new.");
        }

        this.name = name;
    }

    Object.defineProperty(PersonClass2.prototype, "sayName", {
   
        value: function() {
   

            // make sure the method wasn't called with new
            if (typeof new.target !== 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值