class 声明创建一个基于原型继承的具有给定名称的新类: 在没有class之前利用构造函数创建实例,公共的方法定义在prototype对象上,默认是严格模式如:
function Bar(name) {
this.name = name;
this.say = function() {
console.log(this.name)
}
}
Bar.prototype.say = function() {
console.log(this);
console.log(this.name)
}
var bar = new Bar('bar')
bar.say();
console.log(foo);
class 定义一个具名类似函数的对象;
class Foo {
constructor(name) {
this.name = name;
this.say = function() {
console.log(this.name)
}
}
say() {
console.log(this);
console.log(this.name)
}
}
var foo = new Foo('foo')
foo.say();
console.log(foo);
通过constructor构造器接受参数,设置对象的私有属性、
class Foo {}
class Foo {}
1、class的名称不能重复否则报:SyntaxError: Identifier 'Foo' has already been declared,而函数可以定义相同的名称,后面的覆盖前面的
区别:通过类定义的公有方法是不可枚举的,也就是通过Object.keys获取得到方法的名称,而fuction在原型上定义的方法是可枚举的
console.log(Reflect.ownKeys(Bar.prototype));//["constructor", "drinkBar"]
console.log(Reflect.ownKeys(Foo.prototype));//["constructor", "drinkFoo"]
console.log(Object.keys(Bar.prototype));//["drinkBar"]
console.log(Object.keys(Foo.prototype));//[]
2、类声明的构造函数不能通过函数执行符使用,只能通过new 关键字执行:
var ok=new Foo;
ok.drinkFoo()
3、类依然支持表达式和立即执行:
var Foo=class {}
var run= new class {
constructor(name) {
this.name = name;
this.say = function() {
console.log(this.name)
}
}
drinkFoo() {
console.log(this.name);//七鸽
}
}('七鸽')
run.drinkFoo()
4、不存在提升,使用前必须声明:
new Foo()
class Foo{}
5、class内部的方法都是公有的,实现私有方法的一种方案:
class Foo {
constructor(name){
this.a=name
}
say(arg){
speak.call(this,arg)
}
}
function speak(arg){
console.log(arg);
}
var foo=new Foo(3)
foo.say('hello')
6、静态属性和方法的定义(存在兼容性):
class Foo {
static srt= 'humbger'
constructor(name){
this.a=name
}
static eat(arg){
console.log(Foo.srt,arg);//humbger 2
}
say(arg){
speak.call(this,arg)
}
}
Foo.eat(2)
二、class的继承
class Parent {
constructor(name,age) {
this.age=age;
this.name = name
}
say() {
console.log('hello ');
}
parentSay(){
console.log("super::",this.name,this.age);
}
}
class Child extends Parent {
constructor(arg) {
super('root',38)
this.name = arg
}
say(){
//调用父类的方法
super.parentSay();
this.parentSay();
console.log(this.name);
}
}
var ch = new Child('who am I')
注意点:
1、如果子类型中显示说明构造器,在构造器内部不须调用super,实例化父类;
2、如果父类和子类有重名的属性,子类的会覆盖父类的属性。
3、如果父类和子类有重名的方法,子类会重写父类的发方法。