再和“面向对象”谈恋爱 - class(四)

上一篇文章里我引见了一下面向对象编程的观点,在末了终究大喜过望看到了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关键字,如下图:
《再和“面向对象”谈恋爱 - class(四)》

下面我要细致的对照一下ES5ES6的面向对象有什么区分,以及用这类体式格局写出来的对象与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"] 一切要领都是可罗列的

从上面的代码得出以下的结论

  1. 类的本质照样组织函数,实在class就是个语法糖,它的内部照样个组织函数
  2. class声明的对象与ES5声明的对象本质上一样
  3. 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),    //内置对象身上的要领都是不可罗列的
);

从上面的代码得出以下的结论

  1. 自定义对象就是我们声明的一个类似于内置对象的对象
  2. 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里的继续。

    原文作者:kaivon
    原文地址: https://segmentfault.com/a/1190000015906782
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞