接上篇:[ES6]Day05—Set 和 Map 数据结构
面向过程 :分析出解决问题所需步骤,然后用函数把这些步骤一步一步实现,使用时再一个一个的依次调用就行了
举个例子:将大象装进冰箱,面向过程
做法
面向对象 :把事务
分解成为一个个对象
,然后由对象之间分工与合作
。
举个例子:将大象装进冰箱,面向对象
做法
在面向对象程序开发思想中,每一个对象都是功能中心,有明确的分工。
面向对象编程具有灵活、代码可复用、容易维护和开发的优点,更适合多人合作的大型软件项目。
面向对象的特性:
面向过程 | 面向对象 | |
---|---|---|
优点 | 性能比面向对象高,适合跟硬件联系紧密的东西,例如单片机采用的是面向过程编程 | 易维护、易复用、易拓展,由于面向对象具有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更易维护 |
缺点 | 没有面向对象易维护、易复用、易拓展 | 性能比面向过程低 |
一句话概括:面向过程得到一份蛋炒饭,面向对象得到的是一份盖浇饭。
- 定义: 对象是一个具体的事物,看得见摸得着的实物。
- 在JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。
对象是由属性和方法组成的:
属性
:事物的特征,在对象中用属性来表示(常用名词)方法
:事物的行为,在对象中用方法来表示(常用名词)
- ES6新增类的概念,使用
Class
关键字声明一个类,之后以这个类来实例化对象。
类
泛指某一大类(class),抽象了对象的公共部分
对象
特指某一个,通过类实例化一个具体的对象
语法: class 类名{ }
//1.创建一个名为 Star 的类
class Star{
constructor(uname){
this.uname=uname;
}
}
//2.利用类创建对象
var hh= new Star('易烊千玺');
console.log(hh.uname);//易烊千玺
ES6 的类,完全可以看作构造函数的另一种写法。
class Point {
// ...
}
typeof Point // "function"
Point === Point.prototype.constructor // true
上面代码表明,类
的数据类型就是函数
,类
本身就指向构造函数。
class Point {
constructor() {
// ...
}
toString() {
// ...
}
toValue() {
// ...
}
}
// 等同于
Point.prototype = {
constructor() {},
toString() {},
toValue() {},
};
在类的实例上面调用方法,其实就是调用原型上的方法。
class B {}
let b = new B();
b.constructor === B.prototype.constructor // true
上面代码中,b是B类的实例,它的constructor方法就是B类原型的constructor方法。
constructor
方法是类的默认方法,通过new命令生成对象实例时,自动调用
该方法。class Point {
}
// 等同于
class Point {
constructor() {}
}
constructor
方法默认返回实例对象(即this),完全可以指定返回另外一个对象class Foo {
constructor() {
return Object.create(null);
}
}
new Foo() instanceof Foo
// false
constructor函数返回一个全新的对象,结果导致实例对象不是Foo类的实例。
语法:直接在类里加 方法名{}
class Person{
constructor(name,age){ // constructor 构造器或者构造函数
this.name=name;
this.age=age;
}
say(){
console.log(this.name+'你好呀~')
}
//,报错,Unexpected token ','
sing(song){
console.log(this.name+'唱'+song);
}
}
var ww=new Person('ww',21);
var hh=new Person('hh',23);
ww.say()
hh.say()
ww.sing('栀子花开~')
hh.sing('洗刷刷~')
现实中的继承:子承父业,比如我们都继承父亲的姓氏
程序中的继承:子类可以继承父类的一些属性和方法
语法:使用 extends
关键字
class Father{//父类
constructor(name,age){ // constructor 构造器或者构造函数
this.name=name;
this.age=age;
}
money(){
console.log(100)
}
say(){
console.log('自我介绍~我叫'+this.name+'今年'+this.age+'岁')
}
}
class Son extends Father{//子类继承父类
constructor(name,age){ // constructor 构造器或者构造函数
this.name=name;
this.age=age;
}
}
var son =new Son()
son.money(); //100
super
关键字用于访问和调用对象父类上的函数,可以调用父类的构造函数,也可以调用父类的普通函数。
//调用父类的构造函数
class Father{//父类
constructor(x,y){
this.x=x;
this.y=y;
}
sum(){
console.log(this.x+this.y)
}
}
class Son extends Father{//子类继承父类
constructor(x,y){
super(x,y);//调用了父类中的构造函数
this.x=x; //定义子类独有的属性
this.y=y; //定义子类独有的属性
}
}
var son =new Son(1,2)
son.sum(); //3
1.在子类的constructor
方法中,super(x,y)
调用了父类中的构造函数
//调用父类的普通函数
class Father{//父类
say(){
console.log('我是爸爸')
}
}
class Son extends Father{//子类继承父类
say(){
// console.log('我是儿子');
console.log(super.say()+`的儿子`);
// super.say()直接调用父类的普通函数say()
}
}
var son =new Son()
son.say();//我是爸爸的儿子
var son =new Son()
son.say();
son.say()
,查找子类有没有say()
,有,先执行子类中的say()
方法,如果子类中没有,就去查找父类有没有这个方法,有则调用父类的say()
方法。
继承中的属性
或方法
查找采用就近原则
super.say()
直接调用父类的普通函数say()
//子类拓展自己的方法
class Father{ //父类
constructor(x,y){
this.x=x;
this.y=y;
}
sum(){
console.log(this.x+this.y)
}
}
class Son extends Father{//子类继承父类
constructor(x,y){
//利用super 调用父类中的构造函数
//super必须在子类this之前调用
super(x,y);
this.x=x; //定义子类独有的属性
this.y=y; //定义子类独有的属性
}
subtract(){ //子类拓展方法
console.log(this.x-this.y)
}
}
var son =new Son(8,2)
son.sum(); //10
son.subtract(); //6
注意:子类在构造函数
中使用super,
必须在子类this
之前调用,(必须先调用父类的构造方法,在使用子类构造方法)
var s=new Son(1,2);
s.sum(); //报错,Son is not defined,需要把实例化放在定义的后面
class Son{
constructor(x,y){
this.x=x;
this.y=y;
//sum();报错,sum is not defined
this.sum(x,y)
}
sum(){
console.log(this.x+this.y)
// console.log(x+y) 报错,x is not defined
}
}
不存在变量提升
,所以必须先定义类,才能通过类实例化对象this
关键字this
指向问题:constructor
里的 this
,指向创建的实例对象
this
,谁调用了dance 函数
,this就指向谁var that,_that;
class Star{
constructor(uname){
//constructor里的this,指向创建的实例对象:hh
that=this;
console.log(this)
this.uname=uname;
this.btn=document.querySelector('button');
//this.btn的点击事件调用了sing()
this.btn.onclick=this.sing;
}
sing(){
//这里的this,指向button对象,因为其点击事件调用了sing()
console.log(that.uname)//易烊千玺,that里面存储的是constructor里的this
console.log(this.uname)//报错,button对象无uname属性
}
dance(){
//方法里的this,谁调用了dance函数,this就指向谁
_that=this;
console.log(this);
}
}
//实例化
var hh= new Star('易烊千玺');
console.log(that===hh);// true
hh.dance()
console.log(_that===hh);// true
原文链接:
阮一峰:ECMAScript 6 入门