Javascript设计模式与开发实践——面向对象的JavaScript(多态、封装、继承)

本文是根据书籍《JavaScript设计模式与开发实践》而写的读书笔记,因为自己经常学了就忘,因此从现在开始起写博客记录一下,大部分都只是简单介绍下。

前言

设计模式的定义是:在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方法。

通俗一点来说,设计模式是在某种场合下对某个问题的一种解决方案,而设计模式就是给面向对象软件开发中的一些好的设计取个名字。

设计模式的适用性:从某些角度来说,设计模式可能会带来代码量的增加和把系统的逻辑搞得更复炸。但软件开发的成本并非全部在开发解冻,设计模式的作用就是让人们写出可复用可维护性高的程序。

所有设计模式都遵循的原则是:找出程序中变化的地方(不稳定),并将变化封装起来。把可变的不稳定封装起来,剩下的就是不变且稳定的部分,这部分是易于复用的。

为什么我选择JavaScript作为学习设计模式的语言?

首先我是前端工程师,JavaScript是我的主力语言(其实也就是只会这个,哈哈哈);

第二,我个人认为设计模式在前端开发中是非常重要的,因为在编写页面的过程中是有很多地方都是能够通过封装组件来实现组件的复用,减少冗余代码,提高整个项目的可复用性和维护性。

面向对象的JavaScript 1.语言类型

编程语言类型可以分为:静态类型语言和动态类型语言。JavaScript属于动态类型的语言。

静态类型 动态类型
区别   在程序编译时确定变量类型   在程序运行时,待变量被赋值,才会具有某种类型  
优点   在编译时即可发现错误和优化   代码量少、简洁  
缺点   代码量大(强制编写类型声明)   无法保证变量的类型,运行时易导致错误  
举列   Java、C   JavaScript  
2.多态

多态的实际含义是:同一操作作用于不同的对象上面,可以产生不同的解释和不同的执行结果

换句话说,给不同的对象发送同一消息的时候,这些对象会根据这个消息分别给出不同的反馈。比如,鸭和鸡都会叫(操作),但是它们的叫声(结果)却不同,用代码来表示就是:

var sound = function (animal) { if (animal instanceof Duck) { console.log(\'嘎嘎嘎\'); } else if (animal instanceof Chicken) { console.log(\'咯咯咯\'); } }; var Duck = function () {}; var Chicken = function () {}; sound(new Duck()); // 嘎嘎嘎 sound(new Chicken()); // 咯咯咯

虽然上面的代码体现了“多态性”,但是如果当我们需要再加一个动物,比如狗(汪汪汪),就必须得改动 sound 函数。修改代码总是危险的,修改的地方越多,程序出错的可能性就越大。

多态背后的思想是将“做什么”和“谁去做以及怎么去做”分离开来,也就是将“不变的事物”与“可能改变的事物”分离开来。这个时候我们就可以把不变的部分隔离出来,将可变的部分封装起来,这给予我们扩展程序的能力,程序看起来是可生长的,这就是符合开放-封闭原则。修改代码如下所示:

// 把不变的部分隔离出来,即所有动物都会叫(边界情况暂不考虑) const sound = function (animal) { animal.sound(); }; // 把可变的部分各自封装起来 const Duck = function () {}; Duck.prototype.sound = function () { console.log(\'嘎嘎嘎\'); }; const Chicken = function () { Chicken.prototype.sound = function () { console.log(\'咯咯咯\'); }; }; // 执行操作 sound(new Duck()); // 嘎嘎嘎 sound(new Chicken()); // 咯咯咯 // 如果我们新增一个动物 狗 const Dog = function () {}; Dog.prototype.sound = function () { console.log(\'汪汪汪\'); }; sound(new Dog()); // 汪汪汪

多态最根本的作用就是将过程化的条件分支语句转化为对象的多态性,从而消除这些条件分支语句。将行为分布在各个对象中,并让这些对象各自负责自己的行为,这正是面向对象设计的优点。

3.封装

封装的目的是将信息隐藏,封装数据、实现、类型和变化。

3.1 封装数据

在其他语言中有对应的关键字来实现封装,但JavaScript中没有,我们只能依靠JavaScript的作用域特性,外层作用域不能直接访问内层作用域变量的特性来对数据进行封装,代码如下:

const myObject = (function () { const _name = \'wx\'; // 私有(private)变量 return { getName: function () { return _name; // 公开(public)变量 }, }; })(); console.log(myObject._name); // undefined 访问不到 console.log(myObject.getName()); // wx 可以访问

在ECMscript6中还提供了Symbol创建私有属性来保存数据的方法,这个可以后续在JavaScript分类中再单独的写写ES6新增的一些特性。

3.2 封装实现

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzwjyz.html