本书作者熟稔 JavaScript。每位作者各写一章,他们均是各自领域的专家。他们根据自己的侧重点,介绍了 JavaScript不同方面的特点,其中有些特点你只有编写大量代码,在试错的过程中才能发现。随着阅读的深入,你将发现这些挚爱着 JavaScript的推动者到底喜欢它的哪些点。
阅读本书,你还将学到很多知识。我确实受益颇多。但是,请不要误将本书当作教程,因为它比教程更宏大。某些章节是对人们一贯认识的挑战,作者向我们展示了即使是最令人恐惧的特征,也可以成为很有用的工具。有几位作者展示了JavaScript可用来表现自我,俨然是一种艺术形式,而其他作者则分享了成百上千名开发者在代码库中使用 JavaScript时,所需的注意事项和最佳实践。有些作者分享个人经历,其他作者则着眼于未来。
本书的各章内容在写作上没有固定模式可循,甚至有一章内容极为幽默、诙谐,这一章是我有意安排的。我尽可能地给予作者充分的自由,我想看看他们究竟能写出怎样的佳作。他们果然不负所望,内容之精彩令人难以置信。他们最终写出了一本极具 JavaScript 风格的书,每一章都反映了作者的风貌。
第1章 美丽的 mixin
实际上并不是什么大不了的问题,开发者却喜欢整出一个过于复杂的解决方案。
—— Thomas Fuchs
项目开始后,代码逐渐多起来。于是,我们将其封装为函数以便复用。随着项目的推进,封装的函数多得不能再多了。于是,我们寻找复用函数的方法。JavaScript 开发者往往不遗余力地使用"合适"的复用技术。但有时过于追求去做正确的事情,却会错过近在眼前的美景。
类继承
JavaScript开发者,若学过 Java、C++、Objective-C和 Smalltalk,编写 JavaScript代码时,对于用类这种层级结构组织代码,心存近乎宗教般的虔诚。然而人们并不擅长分类。从抽象的超类反向派生出实际的类和类具有的各种行为,不符合常人的认知过程且存在限制,必须先创建超类,其他类才能对其扩展。而更接近对象本质的类,更具一般性,抽象程度更高,我们对具体的子类有了更多了解之后,再去定义类将更加容易。此外,从一般到具体的派生方法,类之间存在紧密耦合问题,比如一类完全定义在另一类之上,生成的模型可能过于死板、脆弱和荒谬("Button是 Rectangle 还是 Control的子类?我跟你讲,Button 继承自 Rectangle,Rectangle继承自Control……不,等会…….")。若不尽早理顺各类之间的继承关系,系统将永远受累于一组存在缺陷的关系。出于偶然或凭借天分,我们也许偶尔也能理顺它们之间的关系,但即使最小化的树结构所表示的心智模式,对我们而言通常也过干复杂,我们无法快速理解它。
类继承适合为现有的、易于理解的层级结构建模,明确地声明FileStream是一种 Input Stream,这没有问题。但如果主要动机是函数复用(通常如此),那么为实现类继承而建立起来的层级结构,很快就会变为充斥着毫无意义的子类型的迷宫,令人感到棘手,并且还会增加代码的冗余程度和维护代码逻辑的难度。
大多数行为是否能映射到客观上"正确"的类别,这点仍值得怀疑。并且,主张类继承的一派也的确遭遇到了一伙狂热分子的挑战,他们同是 JavaScript 的忠诚捍卫者。他们宣称JavaScript是一种基于原型而不是面向对象的语言,任何带有"类"字样的方法根本不适用于JavaScript。但"原型"的含义是什么?原型和类有着怎样的区别?
用通用的编程术语来讲,原型是指为其他对象提供基本行为的对象。其他对象可在此基础上扩展基本行为,加入个性化行为。该过程也称为有差异的继承,有别于类继承的是它不需要明确指定类型(静态或动态),从形式上而言,它也不是在一种类型的基础上定义其他类型。类继承的目的是复用,而原型继承则不一定。
一般而言,开发人员使用原型,通常不是为了分类,而是为了利用原型和对象之间的相似性。
— Antero Taivalsaari,诺基亚研究中心
JavaScript 的每个对象均指向一个原型对象并继承其属性。JavaScript的原型是实现复用的好工具∶ 一个原型实例可以为依赖于它的无数实例定义属性。原型还可以继承自其他原型,从而形成原型链。
到此为止还好理解。但 JavaScript仿效Java,将 prototype 属性绑定到构造器,其结果是多个层级的对象继承通常需要链接构造器和原型来实现。在介绍JavaScript之美的书里,加入JavaScript 原型链的标准实现方法,可能会令读者望而生畏,简单来讲,为了定义继承者的初始化属性,而为基础原型创建一个新实例的做法,既不优雅也不直观。另一种方法【手动复制不同原型的属性,改动构造器(constructor)的属性,以此来伪造原型继承】则更不可取。
构造器—原型链句法,不优雅我们就不说了。它的缺点还体现在需要预先规划,比起真正的原型关系,它的结构更像类继承语言中的传统层级关系;构造器表示类型(类),每个类型被定义为一个(且仅有一个)超类型的子类型,所有属性均通过该类型链来继承。ES6的class关键字只是将现有实现方式形式化。构造器—原型链,句法特征笨拙,确实谈不上优美,撇开这些不谈,传统JavaScript 的原型化程度显然没有某些人认为的那样明显。
ES5 标准引入了 Object.create,以增加原型继承的灵活度,拓展应用场景。该方法允许将原型直接赋给对象,JavaScript 原型不再受限于构造器(和类型的限制),因此从理论上讲,对象可以从其他任意对象获得行为,且不受类型转换的限制∶
var circle = 0bject.create({ area: function(){ return Nath.PI * this.radius * this.radius; ), grow: function(){ thts.radius++; } shrtnk: function(){ thts.radius-; } ));
0bject.create 方法的第2个参数可选,表示继承自哪个对象。不幸的是第2个参数不是对象自身(字面量、变量或参数),而是一个完整的 meta 属性定义∶
var circle = 0bject.create({ /*see above*/) },{ radius:{ writable:true,conftgurable:true,value: 7 } });
假如没人愿意在生产代码中使用这些笨拙的继承方法,那么只好在创建实例后,手动将属性赋给它。即便如此,Object.create方法也只是允许对象继承某个原型的属性。但真实应用场景,往往需要从多个原型对象获得行为,例如,一个人可以兼有雇员和经理身份。
mixin 方法
幸运的是,JavaScript提供了其他实现链式继承的可行方法。比起更严格的结构化语言中的对象,JavaScript 对象能够调用任意的函数属性而不管它们之间的血统关系如
何。换句话讲,JavaScript 函数可见,不要求其是可继承的。基于以上观察,依靠继承建立起来的层级结构的全部合理性像纸牌屋一样轰然倒塌。
函数复用的最基本方法是手动委托,任何公共函数都可以直接用 call1 或 apply 方法调用。这一点很强大,易被忽视。然而,一连串的 call或 apply 语句暂且不提它的烦琐,这种委托方法由于极其方便,甚至还会带来反面效果,有时它实际上有悖于你写代码时所遵循的结构化方面的规则,调用过程非常随意,以至于从理论上来讲,开发人员完全不用考虑如何组织代码。
mixin 方法可以得到较好的折衷效果∶ 鼓励按照主线组织功能,可以发挥类继承的表达能力,但又足够轻便和灵活,避免落入时机尚不成熟时组织代码的陷阱(并免遭因继承关系复杂而导致的头晕目眩),继承链层次较深的单祖先模型存在陷阱。并且,mixin 方法还有一个优点,句法简单,能够与无链接的 JavaScript 原型很好地配合使用。
mixin 基础
从传统意义上讲,mixin是一个类,它定义了一组原本要用实体(一个人、圆或观察者)定义的函数。然而,mixin类被视作是抽象的,因为它不是由自己来完成实例化。相反,具体的类通过复制(或借)mixin 类的函数,继承 mixin 的行为,而不必跟行为的提供者产生正式的关系。
好吧,但这就是 JavaScript,我们开发者没有类可用。这实际上是好事,因为它意味着我们可以使用具备清晰和灵活性特点的对象(实例)∶ mixin 类可以是常规对象、原型或函数等。并且,mixin 过程也变得透明和明确。
应用场景
接下来,我将讨论几种mixin技术,但所有的代码示例都导向同一个应用场景;创建圆形、椭圆或矩形按钮(用传统的类继承方法实现比较麻烦)。下图的方框表示 mixin 对象,椭圆形图案表示实际按钮。
类形式的 mixin
我看了一下谷歌为查询词"javascript mixin"返回的两个页面,发现大多数文章的作者将 mixin 对象定义为一种成熟的构造器类型,其函数集定义在原型上。这可以看作是自然的演化,早期的 mixin 是类,类形式的mixin是JavaScript 中最接近干类的类型。下面是按照该方式实现的一个圆形 mixin∶
【下载地址】
链接:https://pan.baidu.com/s/1pvM8_sSfHMH0r3O_0IslVQ
提取码:5yrc
相关文章
介绍了 JavaScript不同方面的特点,其中有些特点你只有编写大量代码,在试错的过程中才能发现。
FlashFXP绿色版网盘下载,附激活教程 1781
FlashFxp百度网盘下载链接:https://pan.baidu.com/s/1MBQ5gkZY1TCFY8A7fnZCfQ。FlashFxp是功能强大的FTP工具
Adobe Fireworks CS6 Ansifa绿色精简版网盘下载 1565
firework可以制作精美或是可以闪瞎眼的gif,这在广告领域是需要常用的,还有firework制作下logo,一些原创的图片还是很便捷的,而且fireworks用法简单,配合dw在做网站这一块往往会发挥出很强大的效果。百度网盘下载链接:https://pan.baidu.com/s/1fzIZszfy8VX6VzQBM_bdZQ
navicat for mysql中文绿色版网盘下载 1623
Navicat for Mysql是用于Mysql数据库管理的一款图形化管理软件,非常的便捷和好用,可以方便的增删改查数据库、数据表、字段、支持mysql命令,视图等等。百度网盘下载链接:https://pan.baidu.com/s/1T_tlgxzdQLtDr9TzptoWQw 提取码:y2yq
火车头采集器(旗舰版)绿色版网盘下载 1707
火车头采集器是站长常用的工具,相比于八爪鱼,简洁好用,易于配置。火车头能够轻松的抓取网页内容,并通过自带的工具对内容进行处理。站长圈想要做网站,火车头采集器是必不可少的。百度网盘链接:https://pan.baidu.com/s/1u8wUqS901HgOmucMBBOvEA
Photoshop(CS-2015-2023)绿色中文版软件下载 1823
安装文件清单(共46G)包含Window和Mac OS各个版本的安装包,从cs到cc,从绿色版到破解版,从安装文件激活工具,应有尽有,一次性打包。 Photoshop CC绿色精简版 Photoshop CS6 Mac版 Photoshop CC 2015 32位 Photoshop CC 2015 64位 Photoshop CC 2015 MAC版 Photoshop CC 2017 64位 Adobe Photoshop CC 2018 Adobe_Photoshop_CC_2018 Photoshop CC 2018 Win32 Photoshop CC 2018 Win64