Tag Archives: javascript

Flash恐惧症

我发现我在开发上对Flash有恐惧症。Flash/Flex现在作为不可多的的RIA应用的开发平台,有着许多优势。但是我总是排斥使用Flash/Flex。虽然我在Flash5/MX的时代也做过些动画,那个时候还没有成形的ActionScript,还要用telltarget,Flash也并非开放标准的。当时能用Flash做RIA应用是非常了不起的,因为那个时候没有Flex这种套件框架,也没有适用的IDE,虽然我也很想尝试用Flash做一个社区,但是后来失败了。再后来我就再也没有碰过Flash。 然而我倒并不排斥Flash应用,包括AIR,我觉得很多优秀的应用用起来非常不错。究竟是什么令我在开发上如此排斥Flash呢?我仔细分析了一下,想到以下问题: 当时Flash不是开放的。当时Flash只能使用Macromedia Flash来制作,几乎没有其他够用的工具(我记得有个Swiss)。随着Flash的标准开放,现在情况改变了,有不少的第三方工具。不过因为当时Flash的不开放,让我错过了。 当时Flash在其他平台上的支持非常差。当然,现在已经好很多了。不过即使现在,Flash在Linux下的实现还是有些问题,CPU占用率非常高。Flash曾经是没有Linux开发工具的,现在也没有多少,当然后来Adobe推出了Flex for Linux,结果最近看一则新闻说因为Flex for Linux用得太少,所以Adobe要停止维护Flex for Linux了。这样看来,如果要跨平台,无论是开发时还是运行时,Flash比起html+js还是差一些。 过去Flash主要作为动画来使用,文件非常庞大,那时候也很少使用动态加载。现在用Flex做客户端应用非常方便,但是Flex相对于HTML来说,还是过于庞大。同样的,Flex开发套件也太庞大了,尤其是如果把Java也算进去的话。而我使用HTML/JS可以需要用文本编辑器和一个浏览器。 Flash并非事实上的标准,网站可以不使用Flash,却不能不使用HTML。现在主流的浏览器,都支持JavaScript,却不一定有Flash。 其实我认为我害怕使用Flash最关键的是在于我在开发上的思维转变,过去我很喜欢很酷很眩的特效,觉得有了这些东西,程序肯定就很牛B。但后来我意识到这种想法是幼稚的,这些特效都是浮云,要先抓住问题本质,要去掉这些复杂的外观,直接呈现内容。而如果不需要特效,Flash比起html + js就没有明显的优势了,而我更喜欢html+js的简洁快速。 ~~~~~~~~~~~~~~~~~~~~~~~~ Flash作为RIA,目前是如日中天,AIR也是相当流行,但实际上是杀机四伏。 微软也推出了Silverlight与Flash直面竞争。 由于JavaScript的发展,各种JavaScript特效框架的出现,过去需要使用Flash才能实现的很多特效现在可以直接使用js实现,直接消除了一部分对于Flash的需求。 JavaScript的一些工具包,也能实现很多窗体控件,使开发简单,如extjs dojo jquery-ui等,除了IDE上支持不够。这对于Flash的Flex框架也是一种威胁。 Adobe的AIR还比较聪明,没有完全把赌注押在Flash上,兼容了html+js的开发,Mozilla已经推出了Prism来竞争,而Prism的最强大的地方莫过于既有的Web应用可以直接运行在Prism上。 其实对Flash最大的威胁来自于HTML5: 过去JavaScript一直有跨域的问题,而且对长连接支持有些问题,HTML5中的Websocket为Ajax提供了更强大的通讯能力,Flash的优势又进一步减弱了。 利用HTML5中canvas,JavaScript就可以进行高速的2D图形绘制,这也是抢了Flash的市场。 HTML5支持离线存储Dom Stoarge,Flash的又一个特性被直接支持 以上这些标准组件在某些浏览器中已经被支持了,Flash对于浏览器毕竟只是第三方支持,但是HTML5的这些东西将来可都是直接在浏览器核心中的。 我想还有一个不得不提的就是3D了,Flash现在也可以实现3D,但是Flash的3D效果只能算普通,效率也比较低,做复杂的3D应用是不适合的。在这方面,Java Applet却可以调用OpenGL,效率就不在同一个层次上了。而最近Google为Chrome推出的o3d,也是Flash强劲的对手。 所以,我觉得Flash未来的好日子有限。

在SpiderMonkey中产生可调用的对象

我应该对标题做一个更详细的解释:用C语言在SpiderMonkey中产生一个在JavaScript中可以当成函数被调用的对象,换句话说,就是一个非Function的对象,在JavaScript中可以被当成Function进行调用。例如,我有一个Hash对象,当我在var h = new Hash()之后,可以直接调用h(key),h并非一个函数对象,却可以以这种函数调用的方式来获取键key对应的值。 首先,必须要在创建这个Hash类的结构时,将JSClass中的”call”字段设置为相应的函数,如下: static JSBool call_hash(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ /* here the obj refers to the global object, not the callee itself */ *rval = JSVAL_NULL; return JS_TRUE; } static JSClass hash_class = { “Hash”, JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, finalize_hash, 0, 0, [...]

函数式JavaScript编程指南

JavaScript Programming 原文地址:http://www.pfeiffer-mediation.de/remast/javascript.php 翻译:ShiningRay 函数式JavaScript编程指南 简介 你是否知道JavaScript其实也是一个函数式编程语言呢?本指南将教你如何利用JavaScript的函数式特性。 要求:你应当已经对JavaScript和DOM有了一个基本的了解。 写这篇指南的目的是因为关于JavaScript编程的资料太多了但是极少的资料提到了JavaScript的函数式特性。在本指南中,我只会讲解这些基本知识而不会深入其它的函数式语言或这是Lambda算子。 你可以点击所有的例子然后你所看到的代码就会被执行,这样就可以令指南变得具有交互性。你也可以使用这个沙箱来尝试。 第一课 —— 匿名函数 我们将首先介绍匿名函数。一个匿名函数就是一个没有名字的函数。你可以认为他们是一次性函数。当你只需要用一次某个函数式,他们就特别有用。通过使用匿名函数,没有必要把函数一直放在内存中,所以使用匿名函数更加有效率。 例Example: 下面两个函数处理同样的事情,而average在给z赋值结束之后一直保留——但匿名函数则不会。 function average(x,y) { return (x+y)/2; } var z = average(1,3); alert(z); var z = function(x,y) { return (x+y)/2; } (1,3); alert(z); 这很自然得引出了我们下面的一节课函数作为值。 第二课 – 函数作为值 事实上,我们一般在JavaScript中声明函数的方式可以看作是一个简化了的语法(也就是语法糖,syntactic sugar)。 例: 下面两个表达式其实完全一样。所以左边的表达式仅仅是右边的简写。 function average(x,y) { return (x+y)/2; } alert( average(1,3) ); var average [...]

超酷的JavaScript小游戏

http://wholewheatweb.com 乍一看感觉像Flash做的,其实他只用了200行JavaScript代码! 当然,该游戏还是基于 Prototype 1.6 以及Scriptaculous 1.8 看看DIGG上的评论

JavaScript高级程序设计

基本信息 【英文名】Professional JavaScript for Web Developers 【作者】Nicholas C. Zakas 【译者】曹力 张欣 【ISBN】7115152098 【出版时间】2006-9-15 【页码】670 【原出版社】Wrox 【简介】本书从最早期Netscape浏览器中的Javascript开始讲起,直到当前它对XML和Web服务的具体支持,展示了如何充分利用这种功能强大的语言开发自己的应用程序,以解决当今Web开发者面对的商业问题。 活动主页 译者序

JavaScript = C + Lisp

作者: William Taysom 原文地址:http://www.jadetower.org/muses/archives/000307.html 翻译:ShiningRay 我在过去的几周内一直在写JavaScript代码——使用我们的对话框系统来个性化Mozilla。假设你要求:“嘿,电脑,我要教你如何在Amazon.com上找书。首先你象这样进入Amazon,然后在这里输入你要的书的名字。点击“Go”然后……”我的困难在于对Mozilla编码使我的对话框系统可以“看”浏览器中正在进行什么然后自己可以执行这些动作。 由于Mozilla中较高的层次是用JavaScript实现的。所以我一直在废寝忘食研究它(我的Rhino book里面全是我做的书签)我写的越多,我越觉得它像Lisp。 考虑以下代码: semanticAccepter = acceptOnlyIf( acceptNot(emptyTextAccepter), scriptFilter, acceptAny( textAccepter, linkAccepter, formRelatedElementAccepter, linkImageAccepter)); usefulContentOfThePage = new SemTree(semanticAccepter); 这里SemTree是一个对象,它允许你从一个HTML DOM 树中选出某些你感兴趣的节点,去掉那些你不感兴趣的节点。(根本上说,这是一个TreeWalker 类的包装器。)若要建立一个 SemTree ,你要给出一个接受器。一个接受器只是一个判断给定节点是否能被接受的一个函数: function emptyTextAccepter(n) { return (n instanceof Text) && n.data.match(/^\s*$/); } 一旦有了一些基本的接受器和筛选器,很容易就可以定义组合筛选器──一种将筛选器以特殊形式组合起来的函数: function acceptAny() { var disjuncts = arguments; return function(n) { for (var i = 0; [...]

在Java2平台企业版中应用异步JavaScript技术和XML(AJAX)

作者Greg Murray, 2005年6月9日  翻译:ShiningRay@Nirvana Studio2005年9月9日 任何试过过Flickr、GMail、Google Suggest或者是Google Maps的人都会意识到一种新型的动态Web应用正在逐渐浮出水面。这些应用外观和表现都和传统的桌面应用程序很像,而他们不需要依赖于插件或者是特定于浏览器的功能。过去Web应用只是一系列HTML页面,他们任意一部份内容的更改都必须重新载入页面。像JavaScript编程语言和层叠样式表 (CSS)之类的技术已经成熟,可以有效地应用他们来创建高动态的Web应用,而且可以运行在所有的主流浏览器中。本文将会详细介绍你马上就可以使用的一些技术,让他们使你的Web应用像桌面应用更加丰富和更有交互性。 介绍异步JavaScript技术和XML(AJAX) 使用JavaScript技术,一个HTML页面可以异步地对服务器(一般是载入页面的服务器)发送请求并获取XML文档。然后JavaScript可以使用XML文档来更新或改动HTML页面的文档对象模型(DOM)。最近形成了一个术语AJAX(Asynchronous JavaScript Technology and XML)来描述这种交互模型。 AJAX其实不是很新的东西。这些技术对于Windows平台上专注于Internet Explorer的开发人员来说,已经存在好几年了。直到最近,这个技术才被作为Web远程技术或者远程脚本技术被大家了解。Web开发人员也有一段时间曾经使用过插件、Java applet和隐藏框架来模拟这种交互模型。最近发生的变化是,对XMLHttpRequest对象的支持已经成为所有平台上的主流浏览器都包括的特性了。JavaScript技术的XMLHttpRequest对象是。尽管在正式的JavaScript技术标准中并没有提到这种对象,然而今天主流的浏览器都对他提供了支持。而当代的浏览器如Firefox、Internet Explorer以及Safari在JavaScript技术和CSS的支持上有些细微的差别,但是这种差别是可以处理的。如果你要考虑支持较老的浏览器,AJAX也许就不能成为你的解决方法。 基于AJAX的客户端之所以独特的原因是客户端包含了用JavaScript嵌入的特定于页面的控制逻辑。应用JavaScript技术的页面基于事件进行交互,如文档载入、鼠标点击、焦点改变甚至是定时器。AJAX交互使得表现层逻辑更加清晰地与数据分离。一个HTML页面也可以根据需要每次读入适当的数据,而不是每次需要显示一个更改时都重新载入整个页面。AJAX要求一种不同的服务器架构来支持它这种交互模型。以前,服务器端Web应用关注于对每个导致服务器调用的客户端事件都生成HTML文档。然后客户端对每个回应都要重新读入并重新渲染完整的HTML页面。富Web应用(Rich Web Application)关注于,让一个客户端获取一个HTML文档让它表现为一个模板或者是一个容器,可以基于事件并使用从服务器端组件中获取的XML 数据来对文档注入内容。 一些AJAX交互的应用如: 实时表单数据检验:像用户ID、序列号、邮政编码或者是特殊的票据代码这类需要服务器端验证的数据也可以在用户提交表单之前进行验证。 自动补全:像电子邮件地址、姓名或城市名之类的表单数据都可以根据用户情况自动补全。 处理细节操作:根据一个客户端事件,一个HTML页面可以根据现存的一些数据再去获取更多详细的信息,如现在有一个产品列表,客户端可以控制查看单独的产品信息而无需刷新页面。 复杂的用户界面控件:像树型控件、菜单和进度条之类不要求页面刷新的控件也能实现。 页面内刷新数据:HTML页面可以从服务器上查询最新的数据如分数、股指、天气还有其它的特定于应用的数据。 服务器端通知:一个HTML页面可以通过对服务器进行定时查询来模拟一个服务器的事件通知推送,实现像通知客户端一个消息、刷新页面数据或将客户端重定向到另一个页面。 这个列表并未把所有的应用都列出来,但它已经显示了AJAX交互可以让Web应用比从前能做更多的事情。但尽管这些好处是值得关注的,这种方式也有一些缺点: 复杂度:服务器端开发人员必需理解,HTML客户端页面中的表现层逻辑以及生成HTML客户端页面所需的XML内容的服务器端逻辑。HTML页面开发人员必须了解JavaScript技术。如果开发新的框架和发展已有的框架来支持这种交互模型,那么AJAX应用的创建就会越来越简单。 XMLHttpRequest对象的标准化:XMLHttpRequest对象还不是JavaScript技术标准的一部分,这就意味着根据客户端的不同,应用的行为也有所会不同。 JavaScript技术的实现:AJAX交互极大地依赖于JavaScript技术,而由于客户端的原因JavaScript还有一些细微的差别。见QuirksMode.org来了解更多关于浏览器之间区别的内容。 调试:AJAX应用也难于调试,因为流程逻辑是同时嵌在客户端中和服务器上的。 代码可见:客户端的JavaScript可以很容易通过“查看源代码”被人看见。一个没有良好设计的AJAX应用很可能被黑客攻击或被他人剽窃。 当开发人员在使用AJAX交互模型上获得更多的经验后,AJAX技术的框架和模式就会慢慢浮现出来。现在就关注于完全通用的AJAX交互框架,还为时过早。本文和相关的解决方案将关注于在现有的Java 2平台企业版(J2EE)上如何对AJAX进行支持,像servlet,JavaServer Page(JSP)软件、JavaServer Face应用和Java标准标签库(JSTL)。 AJAX交互剖析 现在我们已经讨论了AJAX是什么以及一些高层次的问题。那现在让我们把所有的零件放在一起来展示一个具有AJAX的J2EE应用。 首先考虑一个例子。一个Web应用包括了一个静态HTML页面,或者是一个由JSP生成的HTML页面,这个JSP中还包括了一个HTML表单,它需要服务器端逻辑来对表单中的数据进行检验,而不用刷新页面。一个名为ValidateServlet服务器端组件(servlet)用来提供这种验证逻辑。图一描述了这种具有验证逻辑的AJAX交互的细节。 图1: 一个提供验证逻辑的AJAX交互 以下条目代表了图1中出来AJAX交互的过程: 发生一个客户端事件。 创建和配置一个XMLHttpRequest对象。 XMLHttpRequest对象进行一个调用。 ValidateServlet对请求进行处理。 ValidateServlet返回一个包含了结果的XML文档。 XMLHttpRequest对象调用callback()函数并处理结果。 更新 HTML DOM。 [...]

嵌入JavaScript引擎梗概教程

嵌入JavaScript引擎 梗概教程 作者:Brendan Eich 2000年2月21日 翻译:ShiningRay @ NirvanaStudio 如何启动VM并执行一个脚本 如果不使用任何错误检查这样: JS_起头的返回指针的函数会返回空(null) JS_起头的返回布尔值的函数会返回假(false) (错误照例会被保存在一个JSBool变量ok中)。 JSRuntime *rt; JSContext *cx; JSObject *global; JSClass global_class = { "global",0, JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,JS_PropertyStub, JS_EnumerateStub,JS_ResolveStub,JS_ConvertStub,JS_FinalizeStub }; /* * 你必须有:You always need: * 每个进程一个运行时(runtime), * 每个线程一个上下文(context), * 每个上下文有一个全局对象(global), * 标准类(如Date)。 */ rt = JS_NewRuntime(0×100000); cx = JS_NewContext(rt, 0×1000); global = JS_NewObject(cx, &global_class, NULL, NULL); JS_InitStandardClasses(cx, [...]

JavaScript-C引擎嵌入开发指南

JavaScript-C引擎嵌入开发指南 翻译:ShiningRay@Nirvana Studio原文地址:http://www.mozilla.org/js/spidermonkey/apidoc/jsguide.html JavaScript-C引擎概览 本文档提供了一个JavaScript(JS)引擎的C语言实现的概述,他介绍了你如何在你的应用程序中嵌入脚本引擎来让它们可以使用JS。有两大理由让你在应用程序中嵌入JS引擎:使用脚本来自动操作你的应用程序;同时使用JS引擎和脚本无论何时都可以提供跨平台的功能并消除了应用程序解决方案对平台的依赖性。 受支持的JavaScript版本 本JS引擎支持从JS 1.0版到JS1.4。JS 1.3和更高版本符合ECMAScript-262规范。JS引擎解析、编译和执行包含JS语句和函数的脚本。这个引擎可以处理要用来执行脚本的JS数据类型和对象内存分配,同时它可以清除——垃圾回收——内存中已经不需要的数据类型和对象。 你如何使用这个引擎? 通常,你将JS引擎作为一个共享的资源进行构建。例如,在Windows和Windows NT上,这个引擎是一个DLL文件,在Unix上是一个共享库。然后你把你的应用程序和他连接,同时嵌入式JS引擎应用程序编程接口(API)就可以在你的应用程序中调用了。JS引擎的API提供了以下几种分类的函数: 数据类型操作 运行时控制 类和对象创生的维护 函数和脚本执行 字符串处理 错误处理 安全性控制 调试支持 你在每个嵌入了JS调用的应用程序中将会用到这些功能分类中的某些部分,象运行时控制和数据类型操作。例如,在你调用其他JS功能之前,你必须通过调用JS_NewRuntime函数来新建和初始化JS引擎。其他功能分类,像安全控制,提供一些可选的特性,你可以根据需要在你的应用程序中使用它们。 这个引擎和应用程序有什么关系? 从概念上来讲,JS引擎在你的系统上是一个共享资源。通过在你的应用程序中嵌入引擎API命令你可以向JS引擎传递处理的请求。这个引擎,反过来,处理你的请求,并把返回值或者状态信息返回给你的应用程序。图1.1描述了它们一般的关系: 图 1.1 例如,假设你正在使用JS引擎来使你的应用程序能通过JS脚本自动运行,同时假设你的应用程序运行一个脚本来对一个用户进行身份验证并且设置一个用户对这个应用程序的访问权限。首先,你的应用程序可能新建一个代表用户的自定义JS对象,包括了用户的名字、ID、访问权限和一个可能的用户拥有权限在应用程序中使用的函数的列表。 在这个情况下,你的应用程序给JS引擎发送的的第一个请求可能是对JS_NewObject的调用来新建一个自定义对象。当JS引擎新建了这个对象,他返回一个指针给你的应用程序。你的应用程序可以再次调用JS引擎来执行使用这个对象的脚本。例如,在建立了用户对象之后,你的应用程序会立刻给JS_EvaluateScript传递一个脚本来立刻编译执行。那个脚本可以获得并验证用户信息,然后建立用户对其他应用程序特性的访问权限。 事实上,你的应用程序和JS引擎之间的关系远比图1.1中显示的要复杂的多。例如,它假设你已经为你的平台构建了JS引擎。它还假设你的应用程序包含了jsapi.h还假设应用程序对引擎进行的第一个调用已经初始化了JS运行时。 当JS引擎接受到了一个初始化的请求时,他会为JS运行时分配内存。图1.2描述了这个过程: 图 1.2 这个运行时是一个内存空间,在其中可以维护你的应用程序所使用的变量、对象和上下文。一个上下文是指,针对JS引擎所使用的线程的脚本执行状态。每个同时存在的脚本或者线程都必须有它自己的上下文。一个单独的JS运行时可以包含很多上下文、对象和变量。 几乎所有的JS引擎调用都要求有一个上下文的参数,所以在创建了运行时之后你的应用程序首先要做的一件事情是调用JS_NewContext来至少创建一个上下文。实际你需要的上下文数量由你的应用程序中所期望同时运行的脚本的数量决定。从另一方面说,如果同一时间只有一个脚本被编译执行,那么你就知需要建立单独的一个上下文,你可以对每个脚本重复使用它。 在你新建了上下文之后,你会通常想要初始化引擎内置的JS对象,可以通过调用JS_InitStandardClasses实现。内置的对象有Array,Boolean,Date,Math,Number,和String字符串对象,大多数脚本都会用到。 大多数应用程序也要用到自定义JS对象。这些对象是特定于你的应用程序的。他们通常代表了数据结构和应用程序中脚本使用的方法。要新建一个自定义对象,你要组装一个JS类来生成这个对象,调用JS_InitClass来在运行时设立这个类,然后调用JS_NewObject来在引擎中新建你这个自定义对象的实例。最后,如果你的对象有一些属性,你也许要通过调用JS_SetProperty来设置他们的默认值。 即使你在创建一个对象的时候给JS引擎传递了一个特定的上下文,最后这个对象还是独立于这个上下文存在的。任何脚本都可以和任意上下文相关联来访问任何对象。图1.3描述了脚本和运行时、上下文以及对象之间的关系。 图 1.3 如图1.3所示,脚本和上下文完全是互相独立存在的及时他们可以访问相同的对象。在给定的运行时中,一个应用程序可以任意未分配的上下文来访问任何对象。也可能有时你想确保能为独占的使用而保留某些上下文和对象。在这些情况下,给你的应用程序新建单独的运行时:一个针对共享上下文和对象,另一个(或者更多的,取决于你的应用程序的需求)针对私有的运行时和对象。 注意:同一时间只能有一个线程被授权访问特定上下文。 构建引擎 在你可以在你的应用程序中使用JS之前,你必须将JS引擎构建成一个可共享的库。在大多数情况下,引擎代码已经包括了Make文件来自动构建。 例如,在Unix下,js源代码目录包括了一个基本的Gnu Make文件——Makefile.ref和一个config目录。config目录包括了平台特定的.mk文件来配合Makefile.ref对你的环境进行构建。在Windows NT下,NMake文件是js.mak。 请阅读源代码目录中任何的readme文件,也许其中包括了和更新的编译指导或者其他信息。 嵌入引擎有什么必要条件? 如果要让你的应用程序可以执行JS,就要在你的应用程序代码中嵌入合适的引擎。嵌入一般有五步: 在你的C模块中加入#include jsapi.h来确保编译器知道有哪些引擎的API可以调用。极少部分特殊的JS引擎工作时会要求你包含额外的头文件。例如,要在你的应用程序中调用JS调试器,你要在合适的模块里面包含jsdbgapi.h。 大部分在JS源代码中的其它的头文件不应该被引用。这样做可能会使你的程序依赖于引擎内部的接口,而这些接口可能随着版本发布而更改。 在你的应用程序中提供支持结构和变量声明。例如,如果你打算给JS引擎传递一个脚本呢,提供一个字符串变量保存了你的应用程序的脚本的版本的文字信息。使用jsapi.h中定义的JS数据类型来声明结构和变量。 使用JavaScript编写特定应用的对象。这些对象常常会与操作在你C程序中的结构的结构和方法进行通讯,特别是如果你在使用JS引擎来自动操作你的应用程序。 在程序代码中嵌入合适的JS引擎API调用和变量引用,包括初始化内置JS对象,和创建组成任何应用程序要用的自定义对象。 大多数JS引擎调用都会返回一个值。如果这个值是零或者空,它通常表示一个错误的情况发生了。如果值非零,它一般表示成功;在这些情况下,返回的值常常会是你的程序需要使用的指针,或者存起来留以后引用。很重要的是,你的程序至少应该每次检查JS调用返回的值。 [...]

JavaScript中的类继承

JavaScript中的类继承 DouglasCrockfordwww.crockford.com 翻译 ShiningRay @ www.nirvanastudio.org And you think you’re so clever and classless and free–John Lennon JavaScript一种没有类的,面向对象的语言,它使用原型继承来代替类继承。这个可能对受过传统的面向对象语言(如C++和Java)训练的程序员来说有点迷惑。JavaScript的原型继承比类继承有更强大的表现力,现在就让我们来看看。 Java JavaScript 强类型 弱类型 静态 动态 基于类 基于原型 类 函数 构造器 函数 方法 函数 但首先,为什么我们如此关心继承呢?主要有两个原因。第一个是类型有利。我们希望语言系统可以自动进行类似类型引用的转换cast。小类型安全可以从一个要求程序显示地转换对象引用的类型系统中获得。这是强类型语言最关键的要点,但是这对像JavaScript这样的弱类型语言是无关的,JavaScript中的类引用无须强制转换。 第二个原因是为了代码的复用。在程序中常常会发现很多对象都会实现同一些方法。类让建立单一的一个定义集中建立对象成为可能。在对象中包含其他对象也包含的对象也是很常见的,但是区别仅仅是一小部分方法的添加或者修改。类继承对这个十分有用,但原型继承甚至更有用。 要展示这一点,我们要介绍一个小小的“甜点”可以主我们像一个常规的类语言一样写代码。我们然后会展示一些在类语言中没有的有用的模式。最后,我们会就会解释这些“甜点”。 类继承 首先,我们建立一个Parenizor类,它有成员 value的get和set方法,还有一个会将value包装在括号内的toString方法。 function Parenizor(value) { this.setValue(value); } Parenizor.method(‘setValue’, function (value) { this.value = value; return this; }); Parenizor.method(‘getValue’, function [...]