`
忘忧鸟
  • 浏览: 141850 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

【转】JavaScript面向对象程序设计(8): 优雅的封装还是执行的效率?

阅读更多

优雅的封装还是执行的效率?这是一个悖论。

优雅封装的程序看起来是那么的美妙:每个属性被隐藏在对象之后,你所能看到的就是这个对象让你看到的,至于它到底是怎么操作的,这个不需要你操心。

执行的效率就是另外一回事。就像是C语言和面向对象的C++之间的差别:C++很优雅,但是执行效率,无论是编译后的二进制代码还是运行期的内存的占用,都要比简单的C语言多出一截来。

这个问题在脚本语言中显得更加重要,因为JavaScript根本就是一种解释语言,解释语言的执行效率要比编译语言低很多。
1. 优雅的封装

我们先来看看变量封装。这里的变量不仅仅是属性,也包括函数。

前面已经说过,JavaScript中并没有类这个概念,是我们利用变量作用域和闭包“巧妙的模拟”出来的,这是一种优雅的实现。还是温故一下以前的代码:

function Person() { 
 var id; 
 var showId = function() { 
 alert("My id is " + id); 
 } 
 this.getId = function() { 
 return id; 
 } 
 this.setId = function(newId) { 
 id = newId; 
 } 
} 
var p = new Person(); 
p.setId(1000); 
alert(p.id); // undefined 
// p.showId(); error: function not defined 
var p2 = new Person(); 
alert(p.getId == p2.getId); // false 
 
我们很优雅的实现了私有变量——尽管是投机取巧的实现的。但是,这段代码又有什么问题呢?为什么两个对象的函数是不同的呢?

想一下,我们使用变量的作用域模拟出私有变量,用闭包模拟出公有变量,那么,也就是说,实际上每个创建的对象都会有一个相同的代码的拷贝!不仅仅是那个id,就连那些showId、getId 等函数也会创建多次。注意,考虑到JavaScript函数就是对象,就不会感到那么奇怪了。但是毫无疑问,这是一种浪费:每个变量所不同的只是自己的数据域,函数代码都是相同的,因为我们进行的是同一种操作。其他语言一般不会遇到这种问题,因为那些语言的函数和对象的概念是不同的,像Java,每个对象的方法其实指向了同一份代码的拷贝,而不是每个对象都会有自己的代码拷贝。



2. 去看效率



那种封装虽然优雅,但是很浪费。好在JavaScript是一种灵活的语言,于是,我们马上想到,把这些函数的指针指向另外的一个函数不就可以了吗?


Js代码
function show() {
alert("I'm a person.");
}
function Person() {
this.show = show;
}
var p1 = new Person();
var p2 = new Person();
alert(p1.show == p2.show); // true



这个办法不错,解决了我们以前的那个问题:不同的对象共享了一份代码。但是这种实现虽然有了效率,可是却太不优雅了——如果我有很多类,那么岂不是有很多全局函数?


好在JavaScript中还有一个机制:prototype。还记得这个prototype吗?每个对象都维护着一个prototype属性,这些对象的prototype属性是共享的。那么,我们就可以把函数的定义放到prototype里面,于是,不同的对象不就共享了一份代码拷贝吗?事实确实如此:

function Person() { 
} 
Person.prototype.show = function() { 
 alert("I'm a person."); 
} 
var p1 = new Person(); 
var p2 = new Person(); 
alert(p1.show == p2.show); // true 
 
不过,这种分开定义看上去很别扭,那么好,为什么不把函数定义也写到类定义里面呢?
function Person() { 
 Person.prototype.show = function() { 
 alert("I'm a person."); 
 } 
} 
var p1 = new Person(); 
var p2 = new Person(); 
alert(p1.show == p2.show); // true 
 
实际上这种写法和上面一种没有什么不同:唯一的区别就是代码位置不同。这只是一个“看上去很甜”的语法糖,并没有实质性差别。

最初,微软的.Net AJAX框架使用前面的机制模拟了私有变量和函数,这种写法和C#很相像,十分的优雅。但是,处于效率的缘故,微软后来把它改成了这种原型的定义方式。虽然这种方式不那么优雅,但是很有效率。

在JavaScript中,这种封装的优雅和执行的效率之间的矛盾一直存在。现在我们最好的解决方案就是把数据定义在类里面,函数定义在类的prototype属性里面。
分享到:
评论
1 楼 itsuki 2011-04-10  
prototype和第2种是差不多的,你也可以直接xxx.prototype.show();

相关推荐

    JavaScript面向对象程序设计

    JavaScript面向对象程序设计(1): 前言 JavaScript面向对象程序设计(2): 数组 JavaScript面向对象程序设计(3): 对象 JavaScript面向对象程序设计(4): 函数...JavaScript面向对象程序设计(8): 优雅的封装还是执行的效率?

    JavaScript程序设计课件:面向对象概述.pptx

    JavaScript程序设计 面向过程与面向对象 6.1.1 面向过程与面向对象 1、概念 面向过程(Procedure Oriented)也可称之为“面向记录”,是一种以过程为中心的编程思想。它注重的是具体的步骤,只有按照步骤一步一步...

    javascript 面向对象编程基础:封装

    但是(这里本人要苦大仇深、痛心疾首地说),“而Ajax的出现使得复杂脚本成为必需的组成部分,这就对 JavaScript 程序设计提出了新的要求,很多Ajax应用开始利用JavaScript面向对象的性质进行开发,使逻辑更加清晰。...

    javascript面向对象三大特征之封装实例详解

    主要介绍了javascript面向对象三大特征之封装,简单描述了封装的基本概念、原理,并结合实例形式详细分析了javascript面向对象程序设计中封装的用法与相关操作注意事项,需要的朋友可以参考下

    Javascript 面向对象编程(一) 封装

    学习Javascript,最难的地方...《Javascript高级程序设计(第二版)》(Professional JavaScript for Web Developers, 2nd Edition) 它们都是非常优秀的Javascript读物,推荐阅读。 笔记分成三部分。今天的第一部分是讨

    javascript 面向对象全新理练之数据的封装

    它是面向对象程序设计的三要素之首,其它两个是继承和多态,关于它们的内容在后面再讨论。 关于数据封装的实现,在 C++、Java、C# 等语言中是通过 public、private、static 等关键字实现的。在 JavaScript 则采用了...

    写给大家看的面向对象编程书(第3版).[美]Matt Weisfeld(带详细书签).pdf

    本书是一部独具特色的面向对象技术著作。书中结合代码示例生动透彻地讲述了面向对象思想的精髓,让读者真正学会以对象方式进行思考。此外,本书还讨论了各种与面向对象概念密切相关的应用主题,包括XML、UML建模语言...

    Javascript OOP之面向对象

    面向对象程序设计(Object-oriented programming,OOP)是一种程序设计范型,同时也是一种程序开发的方法。对象指的是类的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和...

    JavaScript的面向对象编程基础

    为了说明 JavaScript 是一门彻底的面向对象的语言,首先有必要从面向对象的概念着手 , 探讨一下面向对象中的几个概念: 一切事物皆对象 对象具有封装和继承特性 对象与对象之间使用消息通信,各自存在信息隐藏 以...

    Javascript简单实现面向对象编程继承实例代码

    本文讲述了Javascript简单实现面向对象编程继承实例代码。分享给大家供大家参考,具体如下: 面向对象的语言必须具备四个基本特征: 1.封装能力(即允许将基本数据类型的变量或函数放到一个类里,形成类的成员或方法) ...

    javascript 面向对象全新理练之继承与多态

    前面我们讨论了如何在 JavaScript 语言中实现对私有实例成员、公有实例成员、私有静态成员、公有静态成员和静态类的封装。这次我们来讨论一下面向对象程序设计中的另外两个要素:继承与多态。

    Object-oriented-programming-for-JavaScript-developers:适用于JavaScript开发人员的面向对象编程的代码存储库

    熟悉JavaScript语言构造的基础知识以及面向对象的编程及其应用程序。 学习使用Node.js在JavaScript中构建可扩展的服务器应用程序 以三种编程语言生成实例:Python,JavaScript和C# 结合使用访问修饰符,前缀,...

    JavaScript王者归来part.1 总数2

     1.5 安全性和执行效率   1.6 一个例子--JavaScript编写的计算器   1.7 学习和使用JavaScript的几点建议   1.8 关于本书的其余部分   第2章 浏览器中的JavaScript  2.1 嵌入网页的可执行内容   2.2 ...

    详解JavaScript对象和数组

    许多高级编程语言都是面向对象的,比如C++、C#和Java等高级程序设计语言,那么一种面向对象语言有哪些基本要求呢?下面我们就通宿地说一下面向对象的一些知识。 一种面向对象语言需要向开发者提供四种基本能力: (1...

    JavaScript前端开发的核心语言前端开发的核心语言

    当今互联网时代,JavaScript已经成为了前端开发的核心语言它是一种高级程序设计语言,通常用于网页的交互和动态效果的实现。JavaScript的灵活性以及广泛的使用使得它变得异常重要,能够为用户带来更好的用户体验。 ...

    JavaScript使用prototype原型实现的封装继承多态示例

    主要介绍了JavaScript使用prototype原型实现的封装继承多态,涉及javascript prototype与面向对象程序设计相关操作技巧,需要的朋友可以参考下

    算法实践(JavaScript & Java),排序,查找、树、两指针、动态规划等.zip

    面向对象: Java是一种纯粹的面向对象编程语言,支持封装、继承和多态等面向对象的概念。这使得Java编写的代码更加模块化、可维护和可扩展。 多线程支持: Java内置了对多线程的支持,允许程序同时执行多个任务。这...

    programming_fundamentals_003:使用面向对象原理重新设计书店

    我们将重新访问目录服务,除了这次我们将以面向对象的思维方式来进行程序的设计。 这意味着将“书籍”视为具有封装数据和行为的对象。 技术 我们将继续在环境中使用Javascript编程语言,并利用称为的测试框架来运行...

Global site tag (gtag.js) - Google Analytics