Javascript编程思想 - 写给C C++程序员

2020-04-16 12:00

发件人: yeqingli(李叶青) 发送时间: 2010年1月18日 9:15

收件人: harrychen(陈子文); bandlin(林培力); jingyang(杨靖); jackbinwu(吴炳杰); macky(钟嘉栋); robbychen(陈柏松); stevenmao(毛小波); yeqingli(李叶青) 抄送: stillzhang(张新辉); freemanxiao(肖立松) 主题: Javascript编程思想——写给C/C++程序员

Javascript编程思想——写给C/C++程序员

By yeqingli

抛砖引玉,给出一些之前学习JS时候的体会,希望引发大家的讨论和思考吧。 本文主要分三节:

第一节 像用C一样使用JS。在不熟悉的时候,语言的学习者会倾向用新语言来模拟旧语言。

第二节 像用JS那样使用JS。熟悉了一个语言以后,语言的学习者开始将语言的特性发挥出来,并且开始消除旧语言的影子。

第三节 JS的Dom对象。最有用、最常用、也是最微秒的部分。只讲问题,详细API请参考《Javascript权威指南》。

第一节 JS本身(像用C一样使用JS)

C/C++ Javascript 备注 变量定义 var v; JS是弱类型语言不需要显式指定变量类型,也可以理解为变量类型不是跟变量本弱类型语言:变量定义的时候int/float/do身绑定的,而是跟变量的值绑不需要显示指定变量类型的编uble/char*等 定的。所以,值一确定,类型程语言。 就确定了,而变量名只是起标识作用。 (c语言的)关联数组 struct 默认拷贝传递,加&符号可默认是引用传递 以引用传递 手工内存管理(C++可以利自动内存管理 用STL进行自动内存管理) “使用关联数组实现数组的粘合”基本上也是现代弱类型动态语言的惯例。 数据的粘合 参数传递 内存管理 这个基本上也是脚本语言的惯例。 程序三大结构 选择/判断/循语法上是一样的。但JS针对数For...in...是更特殊的循环环 组和对象有遍历操作for(... 语句。 in ...) function 程序粘合1 函数定义 程序粘合2 类的定义 Function.prototype 这个下一节会进一步叙述 第二节 JS的面向对象(像JS的作者那样使用JS)

语言泛型 C/C++ 过程式 Javascript 函数式加过程式 备注 自省机制 需要编程实现,如MFC实Js中的对象即关联数组 现的RTTI 静态语言 Class 动态语言 Function.prototype。 动态/静态 面向对象 面向对象 动态语言的意思就是代码可以在运行时修改自身。 基于原型的继承 对象是class对象其实是个关联数组。 的实例 函数式语言

JS实现了函数式的编程泛型(programming paradigm),其中一个重要的特点是,函数是第一层次的数据类型,是和整数、浮点数、字符串这些类型处于同一层次。可以定义类型为函数的变量,并且可以进行一些特定的运算。类型是函数的变量和C语言里面函数指针的差别是:函数指针是一个地址,是没有上下文的,而函数变量是一个对象,包含了运行的上下文。

函数作为第一层次的数据类型,是后面通过原型继承实现面向对象的关键点之一。 没有了这个机制,就无法仅仅赋值关联数组构造真正意义上的类(包含了数据和操作)。

面向对象

面向对象在很多领域并不是非常必要的,比如说单纯的数据处理。即使是写

操作系统内核这种繁重的工作,依然可以使用面向过程很好地完成。但是,面向对象从出现到现在,其最重要的应用领域恐怕是GUI了(复杂的对象关系、交互、消息、异步性导致了复杂的逻辑)。而Web应用的富浏览器化导致了将使用js进行面向对象编程变得重要,因为浏览器端的交互越来越像客户端。

JS的面向对象和C++里面不同,没有提供像class和struct这种定义类型的关键字,

而是使用了Function的prototype通过原型继承来实现的。这里prototype可以理解为JS的一个特殊的关联数组。类的构造是通过关联数组域的定义完成,类的封装是通过关联数组的封装性来实现,而类的继承都是通过关联数组的复制来完成的。(其中用原型实现类继承相当于是在语言层次上实现了设计模式中的原型模式。关于原型模式详情可以参考GoF

的《设计模式》。)

什么是new?

JS的new相当于复制一个关联数组的prototype属性从而生成新的数组,并执行构造函数的过程。

为什么要基于原型继承?

我的观点是,JS的作者为了实现纯粹的弱类型。因为无论是struct和class都是在

定义一个类型,将这些东西引入语言中。就使得JS内建的类型和用户自定义类型的使用上存在本质的差别。一个是隐式指定类型,一个要显式指定类型。

而基于这种prototype的类继承,其过程事实上仅仅是对象的拷贝,并不涉及到显式类型的定义。

但是,并非所有脚本语言都是这样设计的,其他一些脚本语言如python、ruby等,还是利用了明显的class关键字来定义类。

为什么要有一个prototype属性,而不是直接任意关联数组都能new?

Prototype相当于用户和JS运行环境约定的定义类型的关键字,如果所有的关联数组都能new,那么那些不需要实现成类的数据类型的关联数组就要付出额外的开销。(这里可以对比C++中纯数据struct和包含了构造函数的struct的区别)。

所以,prototype可以认为是执行环境和JS语言的约定:叫这个名字的关联数组才进行复制。

自省机制、动态语言及元编程

元编程简单来说就是用程序生成程序。

JS作为一种动态脚本语言,内建支持运行时自省(Introspection/reflection)。JS语言的对象本身提供了hasOwnProperty等函数用于判断自身,而关联数组形式的对象也使得检查对象自身的结构非常轻松。

而JS对于类和对象的实现形式,使得起对象自身可以很容易被修改(只要改掉关联数组相应的属性即可)。C++要运行时修改定义好的类是不行的,但是可以用模版机制生成新的类。

而eval函数真正使得从数据向程序转换变得容易。有个这个机制,程序可以生成字符串形式的代码,并且执行它。C++没有这种函数,所以无法简单地在运行时生成了代码并直接执行并使用其执行结果。

综上所述,使用JS进行元编程是很自然的。我们使用JS写程序的时候可以使用这种方便的元编程机制来减少工作量以及优化代码。类比C++中的场景是使用多态实现同一功能的多种实现方式,并根据运行环境选择需要实例化的对象(可能需要使用工厂模式)。

第三节 JS的Dom对象(JS的不和谐及问题之源)

浏览器(IE、FF)对于Javascript的地位,就像操作系统(Win32、Linux)对于C语言的地位。因而Dom对象对于JS的地位,就类似操作系统API(socket、fork)对于C语言的地位。

而其中的问题是,由于历史原因已经各方面的原因,Dom对象的实现在浏览器里面是不统一,这造成了浏览器兼容一直都是写JS代码中需要很小心的问题。就行用c语言写个server想要在所有操作系统都能编译运行一样,或者类似要C写的操作系统要支持各种硬件平台一样(想想为了兼容平台而写的那些#if/#define以及那些不同的编译选项)。所以,为了处理浏览器兼容,经常要判断某些API或者某些Dom变量是否存在,根据判断结果执行不同的代码(尽管代码实现的功能是一致的)。

Dom接口另一个问题是语言不兼容。也就是说,不能假设Dom里面的函数和对象都是标准的JS函数或对象,拥有所有的JS函数或者对象所拥有的属性和方法。造成这点的原因,

我的一个类比的猜测是,现在常用的操作系统是C语言写的,这些操作系统的API最终通过C语言库的形式暴露出来,所以是完全符合C语言的规范的,而JS的底层运行环境则不是用JS来写的,所以DOM到底要不要完全兼容JS语言,完全是浏览器或者JS引擎的实现者愿不愿意麻烦自己的问题。


Javascript编程思想 - 写给C C++程序员.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:2007-2008有机化学(二)(B) 试卷参考答案

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: