es6中的类
概述:在es6中,class作为对象的模板被引入,可以通过class关键字定义类。
class的本质是function。
它可以看做是一个语法糖,让对象原型的写法更加清晰,更像面向对象编程的语法。
es6和es5的区别,以及为什么要引用类?
1.传统的js中只有对象,没有类的感念,他是基于原型的面向对象语言,对象实例需要一个定义构造函数并且通过new操作符完成。例如:
//函数名和实例化构造名相同且大写(非强制,但这么写有助于区分构造函数和普通函数)
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.say = function() {
return "我的名字叫" + this.name + "今年" + this.age + "岁了";
};
var obj = new Person("laogong", 22); //通过构造函数创建对象,必须使用new 运算符
console.log(obj.say()); //我的名字叫laotie今年88岁了
2.es6需要创建通过原型添加,并且需要new实例,而class就显得比较清晰。
class Person{
//构造方法,用来接收参数
constructor(name,age){
this.name=name;
this.age=age;
}
say(){
return "我的名字叫"+this.name+"今年,"+this.age+"岁了."
}
}
var obj = new Person("laoli",30);
console.log(obj.say());
//由于类实质上就是一个函数,所以它指向构造函数 并且Person等同于person原型的constructor,例如:
console.log(typeof Person); //function
console.log(Person.prototype.constructor==Person) //true
// console.log(typeof obj); //object
// 所以,我们此时可以通过prototype属性来覆盖方法和添加新的方法,例如
Person.prototype.say = function(){
return "我的名字叫做"+this.name+','+"今年"+this.age+".";
}
var obj = new Person("未定义","没有出生");
console.log(obj.say()); //我的名字叫做未定义,今年没有出生.
//添加新方法
Person.prototype.song = function(){
return "我要唱歌了"
}
var obj = new Person()
console.log(obj.song())
// 还可以通过Object.assign方法来为对象动态增加方法
Object.assign(Person.prototype,{
a(){
return "my name is a"
},
b(){
return "my name is b"
}
})
var obj =new Person();
console.log(obj.a()) //my name is a
console.log(obj.b()) //my name is b
constructor中定义的属性可以称为实例属性(即定义在this上面的),hasOwnProperty可以检测是否是实例属性,
例如: console.log(obj.hasOwnProperty('name')) //true
console.log(obj.hasOwnProperty('say')) //false
// in操作符会在通过对象能够访问给定属性时返回true,无论该属性存在于实例中还是原型中。
// console.log('name' in obj);//true
// console.log('sum' in obj) //true
// console.log('chang'in obj)//false ps:chang是未定义的
// 类的所有实例共享一个原型对象,它们的原型都是Person.prototype,所以proto属性是相等的
console.log(obj1.__proto__==obj2.__proto__); //true
// // 所以可以通过__proto来添加方法
obj1.__proto__.addFuntion = function(sex){
return "ceshi"+this.name+sex
}
console.log(obj1.__proto__)
console.log(obj1.addFuntion('女'));//ceshilaoli女
//注意:es6不存在变量名提升,所以需要先定义再使用,否则会报错。
3.静态方法
//静态方法:
class em {
a = 2;
constructor(){
console.log(this.a)
}
static sum(c,d){
console.log(c+d)
}
}
// var obj = new em(); //2 constructor在一刚开始就会调用
em.sum(1,2); //3
4.decorator 是一个函数,用来修改类的行为,在代码编译时产生作用。
5.封装和继承
getter和setter
class Example {
constructor(a, b) {
this.a = a; // 实例化时调用 set 方法
this.b = b;
}
get a() {
console.log("getter");
return this.a;
}
set a(a) {
console.log("setter");
this._a = a; // 自身递归调用 注意:这里_a要生命与实例上的a相区别,不然会出现无限递归
}
} // warning: 1.getter 不能够单独出现
let exam = new Example(1, 2);
extends
// extends 通过 class a extends b 实现继承 例如:
class Son extends Example {
constructor(){
super();
}
static useFa(){
return super.show+1
}
}
// console.log(son.useFa());
// var a = new son();
// Son.useFa();
console.log(Son.useFa())
//在继承父类的时候静态方法只能继承静态方法,不能在原型方法里面继承。