javaScript 语言中,生成实例对象的传统方法是通过构造函数,与传统的面向对象语言(比如 C++ 和 Java)差异很大,ES6 提供了更接近传统语言的写法,引入了 class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
es6 class 与es5的面向对象的区别:
1. 写法不同,使用关键字class
2.当new一个实例,默认有一个constructor方法,且默认返回实例对象(this),也可以返回另一对象
3.类的所有方法都在prototype属性上,但是不可枚举,且每方法结束不能使用分号
4.类的调用必须通过new 一个实例,且类的内部默认使用严格模式
5.不存在变量提升,必须先声明,再调用
6.class的this 默认指向当前类
7.class 的静态方法,使用关键字static,不需new,直接通过类来调用
8. 实例属性和静态属性的写法,实例属性在类的内部直接使用等式(=)写法,也可以写在constructor 方法里,静态属性只需在实例属性前加一个关键字static即可
9.类的继承使用关键字extends,继承机制与es5完全不同,
es5的继承原理:先new子类的实例对象this,再通过将父类的方法和属性添加到子类的this上(parents.call(this))。
Es6的继承原理:先创造父类的实例对象this,所以要构造函数constructor()访问父类的属性使用this,必须先调用super()方法;再通过子类的constructor()来修改this
10.类的继承可以继承原生的构造函数,es5不可以
1. 一般写法(es5 与es6)
//二.ES6,面向对象的写法,calss,class Person{
//constructor():构造
方法是默认
方法,new的时候回
自动调用,如果没有显式定义,会
自动添加
//1.适合做初始化数据
//2.constructor可以指定返回的对象
constructor(name,age){
this.name = name;
this.age = age;
}
getval(){
console.log(
你是${this.name},${this.age}岁
);
}
}
var c1 = new Person("lity",20);
c1.getval();
ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到
注意 :class 类的本质还是一个函数,类本身就指向构造函数。
我们使用Object的一些属性或者方法检测一下 用es6 写的实例对象
方法
//2.isPrototypeOf:检测实例对象是否是某个
函数的原型
console.log(Person.prototype.isPrototypeOf(c1));//true
//3.constructor:查看某个对象的构造
函数
console.log(c1.constructor);
//4.hasOwnProperty:检测某个
属性是否是自己的
属性;不是原型对象上的
属性和
方法
console.log(c1.hasOwnProperty("name"))//true;
//5.in:通过in可以检测
属性是否在自己中(this)或者是原型中存在
console.log("getval" in c1)//原型上存在,true
console.log("name" in c1)//constructor(自己上存在),true
//6.
自定义检测
属性是否是存在
function hasproperty(attr,obj){
return obj.hasOwnProperty(attr)&&(attr in obj);
}
console.log(hasproperty("name",c1));//true;
2.表达式写法
3.class的私有方法(ES6不提供写法)和私有属性(也不提供写法,提案用#识别)
所谓私有方法和私有属性,是指只能在类的内部使用,不能在类外部调用
4.ES6规定Class类没有静态属性,只有静态方法:static
所谓静态,不需要实例化对象,直接调用
5.new.target属性
new是在构造函数生成实例的命令,ES6为new提供了一个属性.target,
返回通过new 命令实例对象的class(构造函数),一般用于类的内部
6.this指向
类的方法内部如果含有this,它默认指向类的实例。但是,必须非常小心,一旦单独使用该方法,很可能报错
如下示例
分析以上示例:prinName 的方法中this,默认指向 类Logger,但是将改方法单独调用,就会报错,this会指向所在运行的环境,所以因为找不到this.print()方法而报错。
针对以上解决this指向的方法:
(1). 使用bind(this)
(2). 使用es6 的箭头函数 ()=>{}
(3).使用Proxy 代理
{}
class Logger {
constructor() {
this.printName = (name = 'there') => {
this.print(`Hello ${name}`);
};
}
// ...
}
//3. Porxy()
.................
7.class 的get() 和set() 方法
与 ES5 一样,在“类”的内部可以使用get和set关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。
拦截了该
方法的返回值
return 'getter';
}
set prop(value) {//当对该
方法赋值时能
获取到该赋值
console.log('setter: '+value);
}
}
let obj = new MyClass();
obj.prop = 123;
// setter: 123
inst.prop
// 'getter'
8.继承
Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。
父类
function Person(name,sex){
this.name = name;//
属性
this.sex = sex;//
属性
}
//定义一个原型
方法
Person.prototype.show = function(){
console.log("我的姓名是"+this.name+"==="+"我的性别是"+this.sex)
}
//子类
function Worker(name,sex,job){
//构成
函数伪装:使用call()
方法绑定this,伪装继承父级的
属性
Person.call(this,name,sex);
this.job = job;
}
//继承
父类的原型
方法:(介绍三种
方法)
//写法一:通过遍历父级的原型一个个赋给子级的原型(es5 的原型是可枚举的,es6的不可以枚举)
(var i in Person.prototype){
Worker.prototype[i] = Person.prototype[i];
}
//写法:重新new一个父级对象赋给子级的原型
Worker.prototype = new Person();
Worker.prototype.constructor = Worker;
//写法三:创建一个原型对象赋给子级的原型;(es5 推荐)
Worker.prototype = Object.create(Person.prototype);
Worker.prototype.constructor = Worker;
var workers = new Worker("小明","男","job")
//es6 的继承
class Person{
constructor(name,sex){
this.name = name;//
属性
this.sex = sex;//
属性
}
}
class Worker extends Person{
constructor(name,job){
super();
this.job =job;
}
}
var workers = new Worker("小明","job")
8.1:super关键字:在子类中不同情况用法不同,既可以当作函数使用,也可以当作对象使用。
(1):super作为函数,只能在constructor中使用:代表父类,返回子类的this
(2):super作为对象,在普通函数中,cuper指向父类的原型对象,可以访问原型对象的属性和方法,注意,父类的实例的属性和方法是访问不了的
(3):super作为对象,在静态方法中,cuper指向的是父类,不是父类的原型对象
示例分析如下:
父类
class Aniamte{
constructor(){
if(new.target == Aniamte){
throw new Error("本类不能实例化,只能有子类继承");
}
}
//静态
方法
static getval(mgs){
console.log("
父类的static",mgs)
}
//普通
方法
setname(){
console.log("该
方法有子类重写")
}
}
//子类
class Dog extends Aniamte{
constructor(){
super();//
调用此
方法,this才用可以用,代表
父类的构造
函数,返回的却是子类
//super() ==
父类.prototype.constructor.call(子类/this)
console.log(this)//Dog {}
this.age = 20;
}
//静态
方法,super在静态
方法中作为对象使用,指向
父类;
static getval(mgs){
super.getval(mgs)//
父类的static niceday
console.log("子类的static",mgs)//子类的static niceday
}
setname(name){
//普通
方法,super作为对象使用,指向
父类的原型对象,
父类.prototype;
super.setname();//该
方法有子类重写
this.name = name;
return this.name
}
};
Dog.getval("niceday");//静态
方法,直接
调用
//var parAni = new Aniamte();//报错
var dogs = new Dog();//new 一个示例对象
dogs.setname("DOYS");////DOYS
8.2.原生构造函数的继承,ES5不支持,ES6利用extend可以继承原生构造函数
函数有以下几种
/* Boolean()
* Unmber()
* String()
* Array()
* Date()
* Function()
* RegExp()
* Error()
* Object()
*/
//实例一:
自定义类Myarray 继承了原生的数组的构造
函数,拥有原生数组的
属性和
方法了
class Myarray extends Array{
constructor(){
super();
console.log(this.constructor.name)//Myarray
}
}
var myarr = new Myarray();
console.log(Object.prototype.toString.call(myarr));//[object Array]
myarr.push(1,2,1);
console.log(myarr.length)//3
总结
以上所述是小编给大家介绍的es6新特性之 class 基本用法解析,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!