class

112 阅读2分钟

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、如果父类和子类有重名的方法,子类会重写父类的发方法。