《程序员》2008.09期有一篇名为《无废话ErLang》的文章,这让我想到了许多的诸如“无废话C”、“无
废话书评”这类的文章,也想到了JavaScript可没有一篇“无废话”,所以决定开个篇来写这个。与这个
决定相关的,索性,这次就写个最简单的吧。

声明一下:如果只想看复杂的东西,不要读这篇文章了。

一、JavaScript最初其实是过程式的

追溯到1.0时代的JavaScript,其实是过程式的。它的基本特性有只有两项,一项是能够直接放在网页的HTML
标签中去接管事件,例如:

  1. <input type="button" value="Go" onclick="alert('hello')">

第二项则是支持一种简单的对象构造器(函数)。其实这个时代的构造器不如说是初始化函数更合适,它应当
这样写:

  1. function MyObject() {
  2. this.xxx = '...';
  3. this.yyy = '...';
  4. }
  5. obj = new MyObject();

所以,早期的JavaScript无可置疑地背上了“基于对象的过程式脚本语言”的名头,这一点也不冤枉。除了
上面两项特性,JavaScript有着一些一般性的脚本语言的性质,例如:
 -整个.js文件一次性装载到执行环境(例如WEB浏览器)中,在经历一次语法分析之后,开始逐行执行;
 -在上述语法分析周期,(具名的)函数和用"var"声明的变量被预先处理在一个标识符表中,以便脚本代码使用;
 -从全局的代码行或函数调用开始执行,整个过程中执行不到的代码不被查错(除第一步中的语法检错外)。
也具有通常的过程式语言的性质,例如:
 -有if/for/while/switch等语句;
 -用function来声明函数,使用"(..)"来声明它的形式参数表,以及表示函数调用和传参;
 -类似于C语言的基本语法,包括使用"{..}"来表示代码块,以及使用"!="等运算符号;
 -一个类似于Java语言的对象操作运算符"."号,和属性、方法这样的基本概念。

好了,现在你看到了一个基本的JavaScript语言,它的代码只有象C一样的函数与语句行,支持非常简单的面
向对象编程。OK,这其实也差不多是JavaScript的全部……嗯……全部的语法基础观念。如果你用过一门哪怕
稍稍入门一点的程序语言,你都会觉得JavaScript其实挺简单的。

是啊,“写个函数,然后调用它”,就这么简单。例如:

  1. function hi() {
  2. alert('hello, world.');
  3. }
  4. hi();

二、稍微复杂一点的是数据类型

JavaScript有六种基本数据类型,分为两类。一类是值类型,即undefined,string, number和boolean;一类
是引用类型,即function和object。检测数据X是何种类型,可以简单地使用"typeof X"来返回一个字符串。

值类型与引用类型在其它高级语言中,是用“访问过程中是传值还是传引用”来区别的。简单说,在下面函数
中:

  1. function foo(X) {
  2. }

X传入的是值本身,还是一个指向该值的引用(你可以想象成指针),表明了X是何种类型。与其它语言不同的
是,JavaScript并不在调用入口上加指示字来说明传值的方法,例如:

  1. function foo(var X) {
  2. // 一般高级语言中,var表明总是传入变量X的引用
  3. }

而是简单的由脚本引擎根据实际传入的X的数据类型来决定如何传值。例如:

  1. function foo(X) {
  2. ...
  3. }
  4. foo('123'); // <- 字符串'123'值
  5. foo(aObj);  // <- aObj是一个对象引用

能这样处理的关键,在于JavaScript类型系统足够简洁。六种基本类型包括了三个哲学化的观念:能执行的
与不能执行的;对象或非对象;有(值)或无(值)。显然,理解这种哲学性的思想并不容易,因为更复杂一层
的、自包含的逻辑是:函数也是对象、值也是对象、无值也是值。

这就是JavaScript类型系统的全部了。如果你想简单的用用,那么你记住下面的就够了:
 -string、number、boolean三种简单值类型是用来传给网页显示的;
 -object用来存放其它的object、funtion或上述简单值类型,并用'.'运算通过一个属性名找到它们;
 -undefined是用来检测数据有效无效的;
 -function是用来执行的。
当然,如果你要成为思想家或者语言学的疯子,那么去思考上面的哲学化命题吧,我不拦着你。

三、能用鼻子想通的就是直接量了

或许很多人都搞不明白JavaScript中的直接量声明,然而它确实是非常简单的。既然我们大多数高级语言都
支持常量声明,甚至最原始的汇编语言也支持立即值——例如:

  1. // in C
  2. #define ABYTE  256
  3. // in delphi
  4. const
  5. ABYTE = 256
  6. ; in asm
  7. mov ah, 256

那么JavaScript当然……必然……可以面无愧色地支持直接量了——他们其实是一个概念。例如:

  1. // in javascript
  2. var
  3. aByte = 256

只不过在理解的时候,一定要切记:所有上述的代码中,所谓直接量或立即值,是指那个'256',而不是那
个变量或常量的标识符ABYTE/aByte。更进一步的,你要知道JavaScript支持了8种直接量声明:
--------------------
数值:支持整数,浮点和0x等进制前缀,以及……等等;
布尔值:true/false;
无值:undefined;
函数:function() { ... },也称为匿名函数;
字符串:使用'..'或"..",支持多行和转义符;
正则表达式:使用/../..,支持g,i,m等正则配置;
数组:使用[..],支持嵌套数组;
对象:使用{...},支持嵌套对象声明;
--------------------
你可以把上述字符量作为一个个体,用在代码——我的意思是表达式或语句行——的任意位置。用鼻子就可以
进行的推论是:

  1. //既然可以写:
  2. aaa = 'hello, ' + 'world';
  3. //那么就必然可以写:
  4. bbb = [1,2,3] + [4,5,6];
  5. //同样也就必然可以写:
  6. ccc = /abc/ + /cdf/
  7. //同样:
  8. // ……

如上的,你可以把所有的直接量放在表达式或语句中间。偶尔的,因为语法解析的必要,你可能需要用一对
括号把这个直接量括起来——否则语法上会出现歧义,例如下面这个:

  1. ddd = (function() {}) + (function() {})

好了,直接量原本就这么简单,你只需要期望自己还有一个没退化的鼻子就好了。

四、原型继承

原型继承可能是这个世界上最简单不过的东西了。

我们假定一个对象是一张表——伟大的Anders就支持我这个假设,他说JavaScript的对象是“属性包”——
这样的一个表中存放的就是“name=value”这样的“名字/值”对。当我们想用下面的代码:

  1. aObj.name

去找值(value)时,就在表里查一下(用delphi的人应该记得TStringList吧)。对象,哦,所谓对象——在
我曾经的理解里——就是“带有继承关系的结构体(struct/record)”。那么,继承关系是?

是这样,如果上面的查找不成功,对于原型继承来说,只需要在aObj这个对象的“原型”中找一下,就成了。
这个原型也是一个对象,记录在构造器函数的prototype属性中。例如:

  1. function MyObject() {
  2. // ...
  3. }
  4. MyObject.prototype = xxx;
  5. var aObj = new MyObject()
  6. zzz = aObj.name;

当在aObj中找不到name这个属性时,按照上面的规则,就会去xxx这个对象中找,也就是试图找找"xxx.name"。
由于xxx本身也是一个对象,也会有一个构造器函数(例如xxxObject()),因此当xxx.name也找不到时,就会
去xxxObject.prototype里面去找……如此……如此深层次的挖掘,直到再也找不到……就返回undefined。

多简单啊,所谓原型继承,只不过是一个简单的检索规则。

反过来说,你需要让aObj能访问到某个成员,也只需要修改一下它(或它们——一指类似aObj的实例)的原型
就好了。这在JavaScript中是非常常用的。例如你想让所有的string都有某个属性:

  1. String.protoype.MyName = 'string'

又例如你想让所有的对象都有某个属性(或方法,或其它什么东东),那么:

  1. Object.prototype.getMyName = function() {
  2. return this.MyName;
  3. }

多么美好,现在String也能getMyName了,函数也能getMyName了,所有没有名字的也有名字了——当然,名
字是undefined。

没名字也是名字,我没想过你会不会变成哲学疯子,对不起。

无废话JavaScript(上)的更多相关文章

  1. 无废话JavaScript(下)

    五.函数式 这个可不是JavaScript的发明,它的发明人已经死了,而他的这个发明还在困扰着我们……如同爱迪生的灯泡还在照耀着我们. 其实函数式语言很简单,它就是一种与命令式语言同样“完备”的语言实 ...

  2. PHP Ajax JavaScript 实现 无刷新附件上传

    普通表单 前端页面 后台处理 带有文件的表单 刷新方式 前端界面 后台页面 无刷新方式 大文件上传 POST极值 upload极值 上传细节 前端页面 后台处理 总结 对一个网站而言,有一个基本的不可 ...

  3. 无废话ExtJs 入门教程二十[数据交互:AJAX]

    无废话ExtJs 入门教程二十[数据交互:AJAX] extjs技术交流,欢迎加群(521711109) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C ...

  4. 无废话ExtJs 入门教程十七[列表:GridPanel]

    无废话ExtJs 入门教程十七[列表:GridPanel] extjs技术交流,欢迎加群(201926085) 在Extjs中,GridPanel用于数据显示,即我们平时说的列表页.在本节中,我们先对 ...

  5. 无废话ExtJs 入门教程十六[页面布局:Layout]

    无废话ExtJs 入门教程十六[页面布局:Layout] extjs技术交流,欢迎加群(201926085) 首先解释什么是布局: 来自百度词典的官方解释:◎ 布局 bùjú: [distributi ...

  6. 无废话ExtJs 入门教程十五[员工信息表Demo:AddUser]

    无废话ExtJs 入门教程十五[员工信息表Demo:AddUser] extjs技术交流,欢迎加群(201926085) 前面我们共介绍过10种表单组件,这些组件是我们在开发过程中最经常用到的,所以一 ...

  7. 无废话ExtJs 入门教程十四[文本编辑器:Editor]

    无废话ExtJs 入门教程十四[文本编辑器:Editor] extjs技术交流,欢迎加群(201926085) ExtJs自带的编辑器没有图片上传的功能,大部分时候能够满足我们的需要. 但有时候这个功 ...

  8. 无废话ExtJs 入门教程十三[上传图片:File]

    无废话ExtJs 入门教程十三[上传图片:File] extjs技术交流,欢迎加群(201926085) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C ...

  9. 无废话ExtJs 入门教程十二[下拉列表联动:Combobox_Two]

    无废话ExtJs 入门教程十二[下拉列表联动:Combobox_Two] extjs技术交流,欢迎加群(201926085) 不管是几级下拉列表的联动实现本质上都是根据某个下拉列表的变化,去动态加载其 ...

随机推荐

  1. 安装Ubuntu 16.04双系统详解(Nvidia显卡)

    Ubuntu16.04双系统安装 一.准备工作 设备:惠普台式机,i5-7400.8G内存.1T机械硬盘.NVIDIA GTX1050显卡.预装系统:Win10. 1.下载ubuntu镜像文件,本人使 ...

  2. 代码查重工具sim

    在瞎搜东西的时候,发现了一个大牛的博客 看起来很厉害的样子...做了一个LaTeX的语法检查并给出适当的提示,上wiki上一查发现他竟然是CVS第一个版本的发明者和开发者...Dick grune这是 ...

  3. lintocde-247-线段树的查询 II

    247-线段树的查询 II 对于一个数组,我们可以对其建立一棵 线段树, 每个结点存储一个额外的值 count 来代表这个结点所指代的数组区间内的元素个数. (数组中并不一定每个位置上都有元素) 实现 ...

  4. freemarker中空值 null的处理 ?exists ?if_exists ?default(“”)

    exists:由空值测试运算符的引入,它被废弃了. exp1?exists 和 exp1??是一样的, ( exp1)?exists 和(exp1)??也是一样的. if_exists:由默认值运算符 ...

  5. (转)微软借力.NET开源跨平台支持,布局物联网平台开发

    今天科技类最大的新闻,莫过于微软宣布.NET开发框架开源计划..NET 开源,集成 Clang 和 LLVM 并且自带 Android 模拟器,这意味着 Visual Studio 这个当下最好没有之 ...

  6. php opensll加解密类

    <?php $pri = "-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQCzJc4RrAqaH2Es02XQ91Cqp/JK0yX893 ...

  7. 什么是P问题,NP问题和NPC问题

    转载自:Matrix67的博客 什么是P问题.NP问题和NPC问题 这或许是众多OIer最大的误区之一.    你会经常看到网上出现“这怎么做,这不是NP问题吗”.“这个只有搜了,这已经被证明是NP问 ...

  8. MySQL主键和外键使用及说明

    摘自网上一个经典的例子:大哥和小弟 一.外键约束 MySQL通过外键约束来保证表与表之间的数据的完整性和准确性. 外键的使用条件:  1.两个表必须是InnoDB表,MyISAM表暂时不支持外键(据说 ...

  9. mysql数据库的存储过程

    一. 什么是存储过程: 存储过程是一组可编程的函数,是为了完成特定功能的SQL语句集,经过第一次编译后再次调用不需要再次编译,创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调 ...

  10. PHP 中的新语法 new static 是个啥意思?

    简单通俗的来说, self就是写在哪个类里面, 实际调用的就是这个类.所谓的后期静态绑定, static代表使用的这个类, 就是你在父类里写的static, 然后通过子类直接/间接用到了这个stati ...