在上一篇文章里我引见了一下面向对象编程的观点,在末了终究大喜过望看到了ES6
供应了类的观点了。那这个类怎样去用,是这篇文章的主题。ES6
给我们供应了一个class
关键字。这个关键字跟之前的var
let
const
很像,它们都是用做声明的,而class
就是用来声明一个类的。
语法
class name [extends]{ //extends是用来继续的,可选参数
//class body
};
注重
- class不能反复声明(与let、const一样)
- 类的本质照样一个组织函数
class Div{ //类
constructor(x,y){ //组织函数
this.x=x; //同享属性,放在constructor里
this.y=y;
}//注重这里是没有逗号的
move(){ //同享要领,这里相当于在Div.prototye上增加要领
console.log('动起来');
}
}
console.dir(Div); //在控制台里看一下与ES5的面向对象顺序有什么差别
在ES5
内里的面向对象,所谓的“类”与组织函数实际上是一个东西,也就是两重角色。而到了ES6
内里真正的类与组织函数现在是星散的,经由过程上面的代码能够看出来,这类写法恰是面向对象的正统写法。同时,我们在控制台里看到这个对象与ES5
的对象区分仅在于显现的名字上多了一个class
关键字,如下图:
下面我要细致的对照一下ES5
与ES6
的面向对象有什么区分,以及用这类体式格局写出来的对象与ECMAScript
的内置对象有什么区分,如许做的目标能让你清楚的邃晓面向对象编程究竟是一种什么样的情势。
1、与ES5对照
const [div1,div2]=[new Div(10,20),new Div(15,20)]; //这两个对象是为了对照他们身上的原型
div1.z=30; //给实例增加一个私有属性
console.log(
typeof Div, //function 组织函数(虽说是类,但本质照样组织函数)
Div.prototype.constructor===Div, //true 类本质照样组织函数(披着羊皮的狼)
//Object.getPrototypeOf要领是用来取对象身上的原型,用它替代__proto__
Object.getPrototypeOf(div1)===Div.prototype, //true 实例的原型就是组织函数的原型
Object.getPrototypeOf(div1)===Object.getPrototypeOf(div2), //true 两个实例的原型都一样,指向组织函数的原型对象
div1 instanceof Div, //true div是它的实例
div1.constructor===Div, //true 实例的组织函数就是类
/*
* 要领申明
* Object.getOwnPropertyNames()这个要领是用来猎取对象身上的一切属性名
* hasOwnProperty()用来推断某个属性是对象自身的(true),照样继续自原型对象的(false)
* Object.keys()返回对象一切可罗列(遍历)的属性名
*/
Object.getOwnPropertyNames(div1),//["x", "y", "z"] 实例自身的属性
div1.hasOwnProperty('x'), //true 实例的属性
div1.hasOwnProperty('move'), //false 这个要领是继续而来的
Object.keys(Div.prototype) //[] 对象身上的要领都是不可罗列的
);
//ES5定义的对象,身上的要领是能够罗列的
function Car(){}
Car.prototype.drive=function(){
console.log('窜的老快了');
}
console.log(Object.keys(Car.prototype)); //["drive"] 一切要领都是可罗列的
从上面的代码得出以下的结论
- 类的本质照样组织函数,实在class就是个语法糖,它的内部照样个组织函数
- class声明的对象与ES5声明的对象本质上一样
- class声明的对象,它身上的要领都不能被罗列
2、与内置对象对照
const [d1,d2]=[new Date(),new Date()]; //声明两个内置对象实例
d1.x=10,d1.y=20,d1.z=30; //给实例增加三个私有属性
console.log(
typeof Date, //function
Date.prototype.constructor===Date, //true
Object.getPrototypeOf(d1)===Date.prototype, //true
Object.getPrototypeOf(d1)===Object.getPrototypeOf(d1), //true
d1 instanceof Date, //true
d1.constructor===Date, //true
Object.getOwnPropertyNames(d1), //["x", "y", "z"]
d1.hasOwnProperty('x'), //true
d1.hasOwnProperty('getDate'), //false 这个要领是继续于Date对象的
Object.keys(Date.prototype), //内置对象身上的要领都是不可罗列的
);
从上面的代码得出以下的结论
- 自定义对象就是我们声明的一个类似于内置对象的对象
- JavaScript的面向对象编程,本质是把某个功用写成一个对象,而且这个对象是在模拟内置对象
增加属性与要领
class
声明的对象一样许可小伙伴们率性的增加属性与要领,包含同享与私有的。
- 同享属性放在
constructor
里,同享要领放在大括号内- 私有属性放在类身上,私有要领放在大括号内同时前面要加
static
关键字- 私有要领里
this
指向类自身,别的要领里的this
指向实例对象
class Bear{
constructor(){
this.name='熊大'; //同享属性(放在constructor里)
}
sleep(){ //同享要领(直接放在大括号里)
this.name='熊二'; //this指向实例,所以在这里给this增加属性照样实例的属性
console.log(`${this.name}爱睡觉`);
}
static gohome(){ //私有要领
//类会默许增加一个name属性,值为class背面的谁人单词
console.log(`${this.name}的家在丛林`); //这里的this并不会指向实例,而是指向类
}
}
//同享属性与要领
const b1=new Bear();
console.log(b1.name); //熊大
b1.sleep(); //熊大爱睡觉
console.log(b1.name); //熊二 sleep里从新定义了name属性,所以在这就被改了
//私有属性与要领
Bear.age=5; //在表面增加私有属性
console.log(b1.age); //undefined 实例不具备
Bear.gohome(); //Bear的家在丛林
//b1.goHome(); //报错,它是私有要领
下篇文章会细致引见class
里的继续。