再和“面向对象”谈恋爱 - 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关键字,如下图:

下面我要详细的对比一下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里的继承。

原文地址:http://blog.51cto.com/13258913/2139956

时间: 2024-08-30 17:54:56

再和“面向对象”谈恋爱 - class(四)的相关文章

再和“面向对象”谈恋爱 - 图片预加载组件(七)

再和"面向对象"谈恋爱 - 对象简介(一)再和"面向对象"谈恋爱 - 对象相关概念(二)再和"面向对象"谈恋爱 - 面向对象编程概念(三)再和"面向对象"谈恋爱 - class(四)再和"面向对象"谈恋爱 - 继承(五)再和"面向对象"谈恋爱 - super(六) 通过前面的六篇文章已经把ES6的面向对象跟大伙说清楚了,大家最关心的应该是来个例子实战一下,别担心自行车都会有.那这篇文章通

再和“面向对象”谈恋爱 - 对象简介(一)

JavaScript中的面向对象是个老生常谈的话题,但是依然有很多小伙伴处于懵逼的状态.面试时候最担心的就是被问到面向对象相关的内容,自己看过无数的资料,依然对面向对象百思不得其解.到底什么是原型?什么是构造函数?什么是继承...一提到这些概念那真是欲哭无泪.悲愤交加,甚至恨的直咬牙!所以有必要重新再谈一次面向对象.同时我也希望通过这几篇文章让你对面向对象由恨生爱,再到爱恨交加,最后爱得死去活来! 对象 ???各位老铁们应该听过一个词叫"一切皆对象",而"面向对象"

再和“面向对象”谈恋爱 - 对象相关概念(二)

上一篇文章把对象的概念讲解了一下,这篇文章要重点解释最让大家犯迷糊的一些概念,包括 构造函数 实例 继承 构造函数的属性与方法(私有属性与方法) 实例的属性与方法(共享属性与方法) prototype(原型) __proto__(原型) 构造函数 构造函数依然是个函数,用来生成对象.所有的对象都是由构造函数创建的 对象哪来的?构造函数生的.而普通函数不能生成对象(不孕不育),构造函数可以生成对象(有生育能力).每个对象都会有一个自己对应的构造函数,但是不代表每个构造函数都会生(生成实例),有不会

再和“面向对象”谈恋爱 - 继承(五)

通过上一篇文章想必各位老铁已经熟悉了class了,这篇文章接着介绍继承.面向对象里最大的特点应该就属继承了.一个项目可能需要不断的迭代.完善.升级.那每一次的更新你是要重新写呢,还是在原有的基础上改吧改吧呢?当然,不是缺心眼的人肯定都会在原来的基础上改吧改吧,那这个改吧改吧就需要用到继承了. 在第二篇文章里说过原型实例跟构造函数之间的继承,并且还讲了一道推算题.最终我们明白,实例为什么能继承原型上的内容是因为prototype,所以在ES5里面想要继承的话就得通过原型,需要对prototype进

再和“面向对象”谈恋爱 - super(六)

在上一篇文章里介绍了继承,那其中说过一个很关键的东西想要继承子类里里必需先调用一个super方法.而super的作用绝对是价值连城!同时super的作用还有多种,并且跟你的使用环境有关系. 1.当作函数使用 super被当作函数使用,这种情况是最普遍的,上一篇文章里已经使用过.它有以下几种作用: super作为函数调用时,代表父类的构造函数 调用super后,this会被改成子类 只能用在构造函数里,用在其它地方报错 { class Father{ constructor(){ console.

面对对象 谈恋爱五大原则浅析!

面向对象编程其实无时无刻不在向我们阐释婚恋观 面向对象编程5大原则,想来跟处对象是一样一样的: 单一职责原则(SRP): 做一个单纯的人,才会有简单<稳稳的幸福-陈奕迅>: 一个类应该仅有一个引起它变化的原因 开放封闭原则(OCP):悟以往之不谏,知来者犹可追: 既开放又封闭,对扩展是开放的,对更改是封闭的! 里氏替换原则(LSP):花心大萝卜才能永远立于不败之地: 子类可以替换父类并且出现在父类能够出现的任何地方,面向接口编程gof 依赖倒置原则(DIP): 谈恋爱经济也要独立呀: 传统的结

价值观不同的人不适合谈恋爱

今天和男朋友狂吵架,整个人都不好了. 起因很简单,就是我俩一起睡了一会,错过了电影开场时间.在睡之前我提醒了他很多遍“设闹钟了么?没设闹钟我设一下.”他设置了闹钟可是他没起来,而且还关掉了闹钟,导致我俩一起错过了开场.这场电影,从上周二开始我就计划要看看.周三首映人太多没去,周四太忙没去,周五问他要不要去他觉得太晚没去,周六晚上想着可以去看电影了呀他觉得明天白天去更好又没去.今天周日终于可以看电影了,结果就这么错过了,特别生气,早知道这样的话我不如早点自己去看了电影何必等到现在. 延伸出来的话题

工作就像谈恋爱

企业和员工就像男人和女人,试用期就像在谈恋爱,转正了就是领了红本.无论那个阶段,双方都在有原则,又要对为对方着想,况且好人和好人不一定能够过一被子,也有因为爱而离婚,不然也不会有这么高的离婚率.一部分传统的人顾全大局,委屈求全,离婚是毒蛇.另一部分,则打破传统最求自己的幸福.二者都没错,看你站在那个角度了.老婆也好,老公也好,且行且珍惜,离多了好人也不一定好了.谁都不愿意,闹得家庭破碎,毕竟对大家都不爽.婚姻如此工作亦如此,公司及领导多站在员工的角度想想,员工也多为企业想想,建利要相互的信任,别

面向对象分析与设计—四色原型模式(彩色建模、领域无关模型)(概念版)

阅读目录: 1.背景介绍 2.问自己,UML对你来说有意义吗?它帮助过你对系统进行分析.建模吗? 3.一直以来其实我们被一个缝隙隔开了,使我们对OOAD遥不可及 4.四色原型模式填补这个历史缝隙,让我们真的看见OOAD的希望 5.在四色原型上运用彩色建模增强视觉冲击力 6.通过四色原型模式建模出领域无关模型 7.结束语:建模时你可以不考虑具体实现,但是建模者要懂技术实现 1.背景介绍 至今我都清楚的记得我第一次被面试官问起什么叫"建模"技术时的情景,那是好几年前的事情了,当时是胸有成竹