前两天去图书馆借了一本《JavaScript之美》,在书架上无意中看到的,想着那就看看吧。

第一章

原型

有些JavaScript爱好者宣称JavaScript是一种基于原型而不是面向对象的语言,任何带有“类”字样的方法根本不适用于JavaScript。但“原型”的含义是什么?原型和类有着怎样的区别?

用通用的编程术语来讲,原型是指为其他对象提供基本行为的对象。其他对象也可在此基础上扩展基本行为,加入个性化行为。该过程也称为有差异的继承,有别于类继承的是它不需要明确指定类型(静态或动态),从形式上而言,它也不是在一种类型的基础上定义其他类型。类继承的目的是复用,而原型继承则不一定。

JavaScript的每个对象均指向一个原型对象并继承其属性。JavaScript的原型是实现复用的好工具。原型还可以继承自其他原型,从而形成原型链。

JavaScript将prototype属性绑定到构造器,其结果是多个层级的对象继承通常需要链接构造器和原型来实现。构造器-原型链句法,不但不优雅,缺点还体现在需要预先规划。ES6的class关键字只是将现有实现方式形式化。

ES5标准引入了Object.create,以增加原型继承的灵活度,扩展应用场景。该方法允许将原型直接赋给对象,JavaScript原型不再受限于构造器和类型的限制。

var circle = Object.create({area: function() {return Math.PI * this.radius * this.radius;},grow: function() {this.radius++;},shrink: function() {this.radius--;}
});

Object.create方法的第2个参数可选,表示继承自哪个对象。不幸的是第2个参数不是对象自身,而是一个完整的 meta 属性定义:

var circle = Object.create({area: function() {return Math.PI * this.radius * this.radius;},grow: function() {this.radius++;},shrink: function() {this.radius--;}
}, {radius: {writable: true, configurable: true, value: 7}
});

或者可以手动将属性赋给它。

即便如此,Object.create方法也只是允许对象继承某个原型的属性,但真实应用场景,往往需要从多个原型对象获得行为。

mixin方法

函数复用的最基本方法是手动委托,任何公共函数都可以直接用call或apply方法调用。

mixin基础

从传统意义上讲,mixin是一个类,它定义了一组原本要用实体定义的函数。然而,mixin类被视作是抽象的,因为它不是由自己来完成实例化。相反,具体的类通过复制(或借)mixin类的函数,继承mixin的行为,而不必跟行为的提供者产生正式的关系。mixin类可以是常规对象,原型或函数等。

应用场景

1:类形式的mixin
先定义一个圆形mixin

var circleFns = {area: function() {return Math.PI * this.radius * this.radius;},grow: function() {this.radius++;},shrink: function() {this.radius--;}
};

再看一个定义按钮行为的mixin

var clickableFns = {hover: function() {console.log('hovering');},press: function() {console.log('button pressed');},fire: function() {return this.action();}
};

如何将mixin对象整合到你的对象之中?你需要借助extend函数。

function extend(destination, source) {for(var key in source) {if(source.hasOwnProperty(key)) {destination[key] = source[key];}}return destination;
}

用刚才创建的两个mixin对象,扩展新对象RoundButton的基础原型RoundButton.prototype:

var RoundButton = function(radius, label, action) {this.radius = radius;this.label = label;this.action = action;
};extend(RoundButton.prototype, circleFns);
extend(RoundButton.prototype, clickableFns);var roundButton = new RoundButton(3, 'send', function(){return 'send';});roundButton.area();
roundButton.fire();

函数形式的mixin
下面我们将圆形和按钮mixin改写为函数。

var circleFns = function() {this.area = function() {return Math.PI * this.radius * this.radius;};this.grow = function() {this.radius++;};this.shrink = function() {this.radius--;};
};var clickableFns = function() {this.hover = function() {console.log('hovering');};this.press = function() {console.log('button pressed');};this.fire = function() {return this.action();};
};

现在原型对象通过Function.prototype.call就能将自己注入到目标对象中去

circleFns.call(RoundButton.prototype);
clickableFns.call(RoundButton.prototype);

这种方法给人的感觉是很贴切,编码风格自然简洁,this总是指向接收者而不是我们不需要的抽象对象,并且,我们不必提防无意中复制了被继承的属性。
带options参数
函数形式的mixin方法还支持通过options参数将行为参数化,以掺杂使用各种行为。看下述示例:

var withOval = function(options) {this.area = function() {return Math.PI * this.longRadius * this.shortRadius;};this.ratio = function() {return this.longRadius / this.shortRadius;};this.grow = function() {this.shortRadius += (options.growBy / this.ratio());this.longRadius += (options.growBy);};this.shrink = function() {this.shortRadius -= (options.shinkBy / this.ratio());this.longRadius -= (options.shinkBy);};
};var OvalButton = function(longRadius, shortRadius, label, action) {this.longRadius = longRadius;this.shortRadius = shortRadius;this.label = label;this.action = action;
};withOval.call(OvalButton.prototype, {growBy: 2, shinkBy: 2});button.area();
button.grow();
button.area();

添加缓存
函数形式的mixin还能做进一步优化,对mixin构造闭包,我们能缓存第一次定义时的结果,由此所带来的性能上的提升非常显著。下面是增加缓存机制的withRectangle mixin:

var withRectangle = (function() {function area() {return this.length * this.width;};function grow() {this.length++, this.width++;};function shrink() {this.length--, this.width--;};return function() {this.area = area;this.grow = grow;this.shrink = shrink;return this;};
})();var RectangleButton = function(length, width) {this.length = length;this.width = width;
};
withRectangle.call(RectangleButton.prototype);var button = new RectangleButton(4, 2);
button.area();

小结

类继承重复用一个对象定义另一个对象,由此形成了一系列紧密的耦合关系,将不同的层级粘结在一起,对象之间的依赖关系非常复杂。相反,mixin极其敏捷,你几乎不需要调整代码库,只要发现了一组通用的,可共享的行为,就可以根据需要创建mixin,而其他所有对象不管在整个模型中扮演什么角色,都可以访问mixin的功能。mixin和对象之间的关系非常自由:mixin的任意组合可应用于任意对象,对象对应用于它的mixin数量也没有限制。这正是原型继承赋予我们的根据机会复用代码的能力。

转载于:https://www.cnblogs.com/sunshine21/p/10155665.html

JavaScript之美读书笔记一相关推荐

  1. 设计模式之美读书笔记

    目录 设计模式之美 读书笔记5- 哪些代码看似面向对象,实际是面向过程编程? 读书笔记4- 封装.抽象.继承.多态分别解决了什么编程问题? 读书笔记3- 我们在讨论面向对象的时候,主要说的是什么? 读 ...

  2. 《高性能JavaScript》(读书笔记)

    这次主要是对<高性能JavaScript>一书的读书笔记,记录下自己之前没有注意到或者需要引起重视的地方 第一章 加载和执行 js代码在执行过程中会阻塞浏览器的其他进程,比如用户界面的绘制 ...

  3. 《JavaScript模式》读书笔记一:基本技巧

    <JavaScript模式>的读书笔记,个人向! 更新进度随我的阅读进度 基本技巧 尽量少用全局变量 防止变量污染 注意JS变量提升问题 尽量使用单一var模式,只使用一个var在函数顶部 ...

  4. 度量相似性数学建模_数学之美读书笔记

    2020年6月读,先通读一遍,随后为写读书笔记又重新读了一遍,收获颇丰,虽然没有很多数学或者编程方面的知识,但正如作者所说,这本书讲述的是道,而非术. 读这本书让我领略到了科学的趣味,并不是枯燥的敲代 ...

  5. 数据分析?他们早就开始用了——数学之美读书笔记

    数据分析?他们早就开始用了? 标题取得很好听,其实就是<数学之美>这本书的读书笔记.这是每一个想学编程了解计算机的人都不应该错过的好书,必须推荐 光 看这个名字,你可能以为它就是一本讲数学 ...

  6. 编程之美 - 读书笔记 - 卖书折扣问题的贪心解法

    <编程之美>读书笔记(四):卖书折扣问题的贪心解法 每 次看完<编程之美>中的问题,想要亲自演算一下或深入思考的时候,都觉得时间过得很快,动辄一两个小时,如果再把代码敲一遍的话 ...

  7. 数学之美-读书笔记6-10章

    文章目录 数学之美 第六章 信息的度量和作用 1信息熵 2信息的作用 3互信息 4延伸阅读 第7章 贾里尼克和现代语言处理 1早年生活 2 从水门事件到莫妮卡·莱文斯基 3一位老人的奇迹 第八章 简单 ...

  8. JavaScript高级程序设计-读书笔记(6)

    第20章 JSON JSON是一个轻量级的数据格式,可以简化表示复杂数据结构的工作量 JSON的语法可以表示一下三种类型的值 l        简单值:使用与JavaScript相同的语法,可以在JS ...

  9. javascript权威指南读书笔记之二——词法结构

    本章讲述的内容,用通俗的语言来说,就是应该注意的地方,这些也许和我们所学的其他语言类似,也许完全不同,比如一开始就介绍说javascript程序中的每个字符都是用两个字节表示的,但有些程序设计者习惯于 ...

最新文章

  1. qt调用mysql调用了存储过_Qt调用Server SQL中的存储过程
  2. 单链表算法设计(含大厂面试题)
  3. 数字图像识别笔记(第一章绪论)
  4. java-集合(三)
  5. c语言二叉树链式存储,C语言 二叉树的链式存储实例
  6. 这是今年前端最常见的面试题,你都会了吗?
  7. Centos下安装nginx步骤解析
  8. matlab做经济地理、地理距离、经济距离空间权重矩阵
  9. Java实现 蓝桥杯VIP 算法训练 会议中心
  10. 分布式系统的概念、特点及常见方案
  11. 免杀工具BypassAv-web使用教程
  12. 使用STM32与MAX30102实现的较为稳定的血氧算法
  13. Java企业商品进销存管理系统
  14. ajax请求406,Ajax请求返回(406不可接受)
  15. Python 爬虫---百度首页
  16. 方格取数问题(网络流24题之一)
  17. matlab 矩阵位移法编程 结构力学,matlab-矩阵位移法编程-结构力学.doc
  18. 腾讯坐标系转化成百度坐标系
  19. 离散型随机变量及其分布律2
  20. 开发者能力大赏,谁是技术知识达人?

热门文章

  1. jz2440恢复出厂设置
  2. Unity角色同时播放两个音效(走路音效+说话音效)
  3. js数组几种常见的操作方法攻略
  4. 简述电信运营商圈内的三大业务领域-B-M-O
  5. 基于java的千千影评网站的设计与实现(论文+程序设计源码+数据库文件)
  6. UGUI内核大探究(十一)ScrollRect与ScrollBar
  7. 安卓day29网络编程 HttpClient AsyncHttpClient 断点续传多线程下载器 HttpUtils
  8. 单片机开发从来不用数据结构?
  9. js实现网页漂浮广告
  10. Android弹幕功能实现,模仿斗鱼直播的弹幕效果