javascript设计模式学习笔记一

1.富有表现力的javascript

  javascript是现在最流行的、应用最广泛的语言之一。所有现代浏览器都嵌入了JavaScript解释器,作为一种语言,它在我们的日常生活中起着非常重要的作用,支持着我们访问的网站,帮助web呈现多姿多彩的界面。

1.1: JavaScript的灵活性

  JavaScript最强大的特性是其灵活性。作为JavaScript程序员,只要你愿意,可以把程序写的很简单,也可以写得很复杂。这种语言也支持多重不同的编程风格。你即可以采用函数式编程风格,也可以采用更复杂一点的面向对象编程风格。即使你根本不懂函数式变成或面向对象编程,也能写出较为复杂的程序。使用这种语言,哪怕只采用编写一个个简单的函数的方式,你也能高效地完成任务。这可能是某些人把JavaScript视同玩具的原因之一。但我们却认为这是一个优点。程序员只要使用这种语言的一个很小的、易于学习的子集就能完成一些有用的任务。这也意味着当你成为一个更高级的程序员时,JavaScript在你手中的威力也在增长。

  先来看一个用不同方法完成同样的任务例子:启动和停止一个动画。

  如果你习惯于过程式的程序设计,那么可以这么做:

  

View Code

  这种方法很简单,但你无法创建可以保存状态并且具有一些仅对其内部状态进行操作的方法的动画对象。下面的代码定义了一个类。你可以把它创建这种对象:

View Code

  上述代码定义了一个名为Anim的类,并把这两个方法付给该类的prototype属性。如果你更喜欢把类定义封装在一条声明中,则可改用下面的代码:

View Code

  另一种编程风格

View Code

  Function.prototype.method用于为类添加新的方法。他有两个参数,第一个是字符串,表示新方法名称;第二个是用于新方法函数。

  你可以进一步修改Function.prototype.method,使其可被链式调用。这只需要让它返回this值即可。

View Code

  1.2 弱类型语言

  在JavaScript中,定义变量时不必声明其类型。但这并不意味着变量没有类型。一个变量可以属于冀中类型之一,这取决于其包含的数据。JavaScript中有三种原始类型:布尔值、数值型和字符串类型(不区分整数和浮点数是JavaScript与大多数其他主流语言的一个不同之处)。此外,还有对象类型和包含可执行代码的函数类型,前者是一种复合数据类型(数组是一种特殊的对象,它包含着一批值的有序集合)。而其他数据类型则按引用传送。如果不了接着一点,你很可能会碰到一些意想不到的问题。

  与其他弱类型语言一样,JavaScript中的变量可以根据所赋的值改变类型。原始类型之间也可以进行类型转换。toString方法可以吧数值或布尔值转变为字符串。parseFloat和parseInt函数可以把字符串转变为数值。双重”非“操作可以把字符串变为布尔值:

View Code

  弱类型的变量带来了极大的灵活性。因为JavaScript会根据需要进行类型转换,所以一般来说,你不用为类型错误操心。

  1.3 函数是一等对象

  在JavaScript中,函数是一等对象。它们可以存储在变量中,可以作为参数传给其他函数,可以作为返回值从其他函数传出,还可以在运行时进行构造。在与函数打交道时,这些特性带来了极大的灵活性和极强的表达能力。

  可以用function(){...}这样的语法创建匿名函数。他们没有函数名,但可以被赋给变量。下面是一个匿名函数的示例:

View Code

  这个函数在定义之后便立即执行,甚至不用赋给一个变量。出现在函数声明之后的一对括号立即对函数进行调用。括号中空无一物,但也并不是非得如此:

View Code

  这个匿名函数与前一个等价,只不过变量没有在函数内部用var声明,而是作为参数从外部传入而已。这个函数也可以返回一个值。这个值可以被赋给一个变量:

View Code

  匿名函数最有趣的用途是用来创建闭包。闭包(closure)是一个受到保护的变量空间,由内嵌函数生产。JavaScript具有函数级的作用域。这意味着定义在函数内部的变量在函数外部不能被访问。JavaScript的作用域又是词法性质的(lexically scoped)。这意味着函数运行在定义它的作用域中,而不是在调用它的作用域中。把这两个因素结合起来,就能通过把变量包裹在匿名函数中而对其加以保护。你可以这样创建类的私有(private)变量:

View Code

  变量foo和bar定义在匿名函数中。因为函数baz定义在这个闭包中,所以它能访问这两个变量,即使是在该闭包执行结束后。

  1.4 对象的易变性

  在JavaScript中,一切都是对象,而且所有对象都是易变的。这意味着你能使用一些在大多数别的语言中不允许的技术,例如为函数添加属性:

View Code

  这也意味着你可以对先前定义的类和实例化的对象进行修改:

View Code

  在这个例子中,类的getGreeting方法是在已经创建了类的两个实例之后才添加的,但这两个实例仍然能获得这个方法,其原因在于prototype对象的工作机制。对象alice还得到了displayGreeting方法,而别的实例却没有。

  与对象的易变性相关的还有内省(introspextion)的概念。你可以在运行时检查对象所具有的属性和方法,还可以使用这个信息动态实例化类和执行其方法(这种技术称为反射(reflection)),甚至不需要在开发时知道它们的名称。这些技术在动态脚本编程中发挥着重要作用,而静态语言(例如c++)则缺乏这样的特性。

  在JavaScript中,任何东西都可以在运行时修改。这也是一个强有力的工具,许多在别的语言中无法办到的事都能借助于它而办到。当然,这也尤其不利之处。你可以定义一个具有一套方法的类,却不能肯定这些方法在以后总是完好如初。这是JavaScript中很少进行类型检查的原因之一。这个问题将在下一章讲述鸭式辨型(duck typing)和接口检查时进行探讨。

  1.5 继承

  继承在JavaScript中不像在别的面向对象语言中那样简单。JavaScript使用的是基于对象的(原型式(prototypal))继承,他可以用来模仿基于类的(类式(classical))继承。

  1.6 JavaScript中的设计模式

  (1)可维护性。 设计模式有助于降低模块间耦合程度。这是对代码重构和换用不同的模块变得更容易,也使程序员在大型团队中的工作以及其他程序员的合作变得更容易

  (2)沟通。设计模式为处理不同类型的对象提供了一套通用的术语。程序员可以更简明地描述自己的系统的工作放式。你不用进行冗长的说明,往往这样一句话就足够了:”它使用了工厂模式“。每个模式都有他自己的名称,这意味着你可以在较高层面上对其进行讨论,而不必涉足过多的细节。

  (3)性能。某些模式是起优化作用的模式。它们可以大幅提高程序的运行速度,并减少需要传送到客户端的代码量。这方面最重要的列子是享元模式和代理模式。

你也可能出于如下两个理由二不使用设计模式。

  (1)复杂性。获得可维护性往往要付出代价。那就是代码可能会变得更加复杂、更难被设计新手理解。

  (2)性能。尽管某些模式能提升性能,但多数模式对代码的性能都有所拖累。这种拖累可能有点微不足道,也可能完全不能接受,这取决于项目的具体需求。

  • 实现设计模式比较容易,而懂得应该什么时候使用设计模式则较为困难。未搞懂设计模式的用途就盲目套用,是一种不安全的做法。你应该尽量保证所选用的模式就是最恰当的那种,并且不要过度牺牲性能。

  1.7 小结

  JavaScript的丰富表现力是其力量之源。即使这种语言缺少一些有用的内置特性,拜其灵活性所赐,你也能自己加入这些特性。完成一项任务可以有多种方式,你也可以根据自己的技术背景和喜好选择编写代码的方式。

  JavaScript是弱类型语言。程序员在定义变量时并不指定其类型。函数是一等对象,并且可以动态创建,因此你可以创建闭包。所有对象和类都是易变的,可以在运行时修改。可供使用的继承范型有两种,即原型式继承和类式继承,它们各有其优缺点。

  JavaScript中的设计模式皮有助益,但其不当应用也会产生负面效果。在JavaScript这类轻灵的语言中,过度复杂的架构会很快把应用程序拖入泥沼。你使用的编程风格和选择的设计模式应该与所要完成的具体工作相称。    

  

posted @ 2020-05-20 22:20  进军码农  阅读(176)  评论(0编辑  收藏  举报