概述

《你不知道的JavaScript》中有这么一段话:不幸的是,将类和继承的设计模式思维带入Javascript的想法是你所做的最坏的事情,因为语法可能会让你迷惑不已,让你以为真的有类这样的东西存在,实际上原型机制与类的行为特性是完全相反的。

js的原型机制本质上是行为委托机制。行为委托认为对象之间是兄弟关系,互相委托,而不是父类和子类的关系。

面向类的编程

class Polygon {constructor(height, width) {this.name = 'Polygon';this.height = height;this.width = width;}
}class Rectangle extends Polygon {constructor(height, width) {super(height, width);this.name = 'Rectangle';}
}class Square extends Rectangle {constructor(length) {super(length, length);this.name = 'Square';}
}

如上所示,是一个四边形——矩形——正方形的类关系图。看起来设计的很好,但是由于他们的层级关系,他们有这些缺陷:

  1. 每次都要写constructor,有时还要去写prototype。
  2. 如果矩形这个类要增加一个行为,但是这个行为在正方形中不需要怎么办?
  3. 如果要在矩形和正方形之间再增加一层,要怎么办?

用面向类的设计模式,如果遇到上面3个问题,处理起来会很麻烦,这就导致整个架构非常难扩展。原因是在设计整个类的架构的时候,我们已经规定好了每个类的行为以及层级结构,如果后续它们有变动,就会触及到架构问题,所以修改起来会很麻烦。

行为委托

怎么解决上述的问题1呢?方法是利用行为委托。

let polygon = {init: function(width, height){this.width = width;this.height = height;this.setName();},setName: function() {this.name = 'polygon';}
}let rectangle = Object.create(polygon);rectangle.setName = function() {this.name = 'rectangle';
}//初始化一个polygon
const a = Object.create(polygon);
a.init(2,3);//初始化一个rectangle
const b = Object.create(rectangle);
b.init(3,4);//初始化一个rectangle
const c = Object.create(rectangle);
c.init(4,5);

可以看到,利用Object.create方法,使rectangle的prototype委托了polygon对象,从而能够使用polygon对象的各种方法。这样做的优点是,整个过程非常简洁,我们不需要去探究prototype,也不需要去管constructor。

值得一提的是,我们可以通过Object.assign来扩充rectangle对象的方法,而不需要一条条去写rectangle的方法。实例如下:

Object.assign(rectangle, {setName: function() {this.name = 'polygon';},setWidth: function(width) {this.width = width;},setHeight: function(height) {this.height = height;}
});

无类编程

为了解决问题2和3,我们打算降低层级,对所有的类进行“扁平化”管理,即是说,让Polygon作为最底层的类,然后所有的类都继承自它,这样我们就非常好扩展了。实例如下:

class Polygon {constructor(height, width) {this.name = 'Polygon';this.height = height;this.width = width;}
}class Rectangle extends Polygon {constructor(height, width) {super(height, width);this.name = 'Rectangle';}
}const rectangleMixinPublic = {rectanglePublic1: function(){},rectanglePublic2: function(){}
}const rectangleMixinPrivate = {rectanglePrivate1: function(){},rectanglePrivate2: function(){}
}Object.assign(Rectangle.prototype, rectangleMixinPublic, rectangleMixinPrivate);class Square extends Polygon {constructor(length) {super(length, length);this.name = 'Square';}
}const squareMixinPublic = {squarePublic1: function(){},squarePublic2: function(){}
}const squareMixinPrivate = {squarePrivate1: function(){},squarePrivate2: function(){}
}Object.assign(Square.prototype, rectangleMixinPublic, rectangleMixinPrivate,squareMixinPublic,squareMixinPrivate);

从上面的代码可以看到,通过利用扁平化使类都继承于基类,然后利用Object.assign方法进行扩展prototype,使整个架构非常灵活。

其它

当然,我上面只是举了一个例子来说明这几种编程方式,它们的具体应用还有很多方面,比如行为委托还用于封装行为,无类继承还可以通过函数封装成函数式编程的形式。

转载于:https://www.cnblogs.com/yangzhou33/p/9196788.html

js中的行为委托和无类编程相关推荐

  1. JavaScript系列—简述JS中的事件委托和事件代理

    JS中的事件委托和事件代理 什么是事件委托? 事件委托还有一个名字叫事件代理,JS高程上讲:事件委托就是利用事件冒泡,只制定一个时间处理程序,就可以管理某一类型的所有事件.我用取快递来解释这个现象: ...

  2. 深入理解js中的事件委托

    事件委托是前端面试的经典面试题型,上次面试给我整的一脸懵逼,好尴尬.准备找工作的小伙伴赶紧学习学习,也许会对你有帮助. 事件委托原理 事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类 ...

  3. js中的数据类型分为两大类分别是什么_数据类型有这么重要吗?

    一个没有得到重视的知识点, 数据类型 每种语言都有自己的数据类型,下面以javascript为例 类型的分类 js的数据类型可以分为 两大类: 1,值类型 (String,Number,undefin ...

  4. js中的事件委托或是事件代理详解(转载)

    起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没弄明白,写这个一是为了备忘,二是给其他的知其然不知其所以然的小伙伴们以参考: 概述: 那什么叫事件委托呢?它 ...

  5. JS中的事件委托/事件代理详解

    起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没弄明白,写这个一是为了备忘,二是给其他的知其然不知其所以然的小伙伴们以参考: 概述: 那什么叫事件委托呢?它 ...

  6. JS中的事件委托 / 代理详解

    [前言] 事件委托/代理是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的 [主体] 概述: 那什么叫事件委托呢?它还有一个名字叫事件代理,JavaScript高级程序设计上讲:事件委托就是利用 ...

  7. js中的事件委托或是事件代理详解

    参考文章:https://www.cnblogs.com/liugang-vip/p/5616484.html 概述 事件委托也叫事件代理,JavaScript高级程序设计上讲:事件委托就是利用事件冒 ...

  8. JS 中的事件委托是什么?

    大家好,我是前端西瓜哥.今天我们来认识一下事件委托. 所谓事件委托,就是将原本应该在当前元素绑定的事件,放到它的祖先元素上,让祖先元素来委托处理. 事件流 事件流指从页面中接收事件的顺序,也可理解为事 ...

  9. js中JSON.stringify用于自定义的类

    参考:http://stackoverflow.com/questions/7356694/how-to-json-stringify-a-user-defined-class-in-javascri ...

  10. js中的直接赋值和引用赋值

    在JS中,数据分为两大类:基本数据类型 和 引用数据类型:基本数据类型包括: string.number.Boolean.null.undefined.symbol.biglnt七大类,引用数据类型包 ...

最新文章

  1. jvm性能调优 - 02JVM中内存区域
  2. JSP基础(4)-JavaBean
  3. NC16886 炮兵阵地
  4. Openssl的证书格式转换
  5. SqlServer按时间自动生成生成单据编号
  6. OJ1069: 向Z同学学习
  7. ORA-01552 :非系统表空间 'xxxx'不能使用系统回退段
  8. 计算机网络—基础概念
  9. Java笔记——泛型擦除
  10. php+ddos原理,PHP DDos的几个防御方法详解_PHP教程
  11. 采用Zigbee和Raspberry Pi的太阳能/燃气热水器自动控制系统
  12. linux gz解压 指定目,linux解压tar.gz到指定文件夹或目录
  13. CodeMeter 软件加密技术
  14. Layui的管理系统的模板
  15. Udacity 无人驾驶仿真环境搭建实现自动驾驶小车
  16. 计算机地图制图期末考试题,计算机地图制图原理思考题.doc
  17. 举个栗子!Tableau 技巧(127):购物篮分析 Market Basket Analysis 之关联购买
  18. 区块链共识机制:分布式系统的Paxos协议
  19. Oracle转换MySql之递归start with
  20. 管理理念:星巴克-文化成就品牌传奇

热门文章

  1. php封装app微信支付
  2. 二十四、Java集合框架(二)
  3. mac 2018 idea 无法 import导入或打开maven 项目
  4. JavaScript 页面刷新方式汇总
  5. java字符串直接比较_java中对于字符串的比较直接用“==”合适吗?
  6. 2019最新 Java商城秒杀系统的设计与实战视频教程(SpringBoot版)_1-4系统的整体演示...
  7. Atcoder Grand Contest 036 D - Negative Cycle
  8. BTrace简介与使用说明
  9. 【转】解决“你没有权限访问,请与网络管理员联系”
  10. web测试 结果存储类型为“Database”,但尚未指定结果储存库连接字符串