对象的可变性
在JavaScript中,任何东西都是对象(除了三种基本数据类型外,但其实在需要的时候它们会自动转换为对象),而且,任何对象都是可变的。这两者将使你可以使用一些其他语言所不允许的技术,如为函数设定属性等。
function displayError(message) {
displayError.numTimesExecuted++;
alert(message);
};
displayError.numTimesExecuted = 0;
同样你可以在类被定义后或被实例化后对它进行修改。
/* Class Person. */
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype = {
getName: function() {
return this.name;
},
getAge: function() {
return this.age;
}
}
/* Instantiate the class. */
var alice = new Person('Alice', 93);
var bill = new Person('Bill', 30);
/* Modify the class. */
Person.prototype.getGreeting = function() {
return 'Hi ' + this.getName() + '!';
};
/* Modify aspecific instance. */
alice.displayGreeting = function() {
alert(this.getGreeting());
}
在这个例子中,在类的两个实例对象被创建后又为该类增加了getGreeting方法。根据prototype原型对象的原理这两个实例仍然可以拥有这个方法。但只有Alice拥有displayGreeting方法,其他的实例则没有。
和变量动态性相关的一个概念是反射。你可以在运行时检测一个对象拥有哪些属性和方法。你可以使用这个技术实例化一个类并动态执行方法,而不需要知道方法名字(通过反射的方法)。这些是动态脚本的一些很重要的特性,是静态语言(如C++)等所不具有的。
这本书中模拟创建传统的面向对象特性所使用的大多数技术中都是使用对象可变性和反射来实现的。如果你曾经使用过像C++、Java这些不允许对实例进行继承及不允许对声明后的类进行修改的这类语言,你可能会觉得JavaScript的这些特性有点奇怪。在JavaScript中,所有的一切都可以在运行时被修改。这是一个很强大的特性,它使你可以完成其它语言所不可能完成的一些事。然后,它也有一个缺点,它不能保证为类定义的一些方法在后面的程序中仍能保持原状,它很有可能会被破坏。这也是JavaScript中类型检测很少见的一部分原因。我们在第二章讨论关于避免类型检查和界面检查时会讲解这些。
继承 在JavaScript中继承不如其他面向对象语言直接易懂。JavaScript采用的基于对象(原型)的继承,通过此方法可以模拟基于类的继承。本书中我们讲解了两种方式,你可以根据你的代码使用其中的一种方式。通常来说其中的一种会更适用于某个特定的任务。每种方式也有不同的性能特点,这通常是决定使用哪种方式的一个重要因素。这是一个很复杂的话题,我们在第四章再讨论。
JavaScript中的设计模式 1995年,Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides出版了一本名叫《设计模式》的书。编入这本书的目录的对象能彼此以不同的方式相互作用,并且它在不同类型的目标周围创造一种公用词汇。创造这些不同类型的目标的蓝图被称为设计模式。这本书以语言无关的方式描述这些模式,以便于将其用到任何地方。现在你手中的这本书就是将这些模式应用到了特定的语言JavaScript中。
JavaScript语言如此神奇以至于你可以充分发挥自己的想象力将设计模式应用到你的代码中。这里有三个有关为什么你要将设计模式应用到JavaScript中的主要原因:
1、可维护性:设计模式有助于使您的模块更好的实现松耦合。这使得你可以更容易的重构你的代码和更换不同的模块。这也使你可以更好的在大型团队中进行工作,并更好的和其他程序员合作。
2、便于交流:设计模式提供了一些公用的词汇来描述不同类型的任务目标。这使得程序员可以更简单的描述系统的工作方式而不用进行繁琐的描述,比如你可以说:“这里使用了工厂模式。”特定模式的命名使你可以不用深入细节,从而在更高的层级进行讨论问题。
3、性能:我们这本书提到的一些模式是最佳化模式。他们可以极大的提高你的程序的运行速度,并减少发送到客户端的代码量。flyWeight(第十三章)和Proxy模式(第十四章)是有关于此的一些很重要的例子。
这里也有两个你可能不想使用设计模式的原因:
1、复杂性:可维护性往往需要一些成本,那就是你的代码可能变得越来越复杂而且对于新程序员很难去理解。
2、性能问题:虽然一些模式可以提升性能,但大多数的模式会带来一些轻微的性能开销。根据你项目的具体要求,这些开销的影响可能被忽略不计,也可能根本不能被接受。
模式的实现是简单的,懂得使用哪个模式以及什么时候使用才是最难的。不加考虑的将一些设计模式应用到你的代码中是非常危险的。花费点功夫以确保你使用的模式是最合适的,并且保证对性能的影响在可接受范围之内。
本章摘要 神奇的JavaScript提供了强大的功能。尽管它本身缺乏一些有用的内置特性,但它的灵活性使你可以自己为其添加这些特性。根据你的背景和个人喜好,你可以用多种不同的方式来完成一个任务。
JavaScript是弱类型的,程序员在定义变量时不需要声明类型。函数是第一型的并且可以被动态的创建,并且你可以创建闭包。所有的对象和类都是可变的,他们可以在运行时被修改。有两种继承方式可以被使用:原型方式和经典方式,每种方法都有其优点和缺点。
在JavaScript中,设计模式可以打来很大的益处,但如果使用不恰当也会带来很大的害处。在类似于JavaScript的这些轻量级语言中,过于复杂的架构很容易是一个程序瘫痪。一定要保证你的编程风格和使用的模式是适合你的工作的。
阅读(264) | 评论(0) | 转发(0) |