zoukankan      html  css  js  c++  java
  • 《JavaScript编程精解》简明读书心得下

    这是《JavaScript编程精解》简明读书心得 的下半部分。这本书的下半节有两章客户端JavaScript内容。由于这部分内容比较繁杂,而概念比较简单,而且很多工作都可以用JQuery来完成,所以我读这本书的时候,这部分就直接浏览了一遍。因此这下半部分只有两节内容,模块化和正则表达式。

    模块化的JavaScript

    比起C#中可以轻松地在类中声明私有字段、继承类、封装接口、生成命名空间,JavaScript简直太可怜了——它不提供任何模块化的原生支持。事实上,我们只能通过一些JavaScript的特性来“模拟”出模块的特点。模块的特点是“封装”,即模块的使用者可以对模块内的细节一无所知,其目的就是希望当其他模块发生变化时,自身可以不变,增强了代码的复用性。在JavaScript中,这是通过以下两个特性来完成的:

    • 1、函数内部的局部变量对外不可见(闭包) 
    • 2、对象的字段只能通过对象调用(这好像又是废话)

    用函数封装变量,使得不需要出现在全局作用域的变量不出现在全局作用域。比如我希望获得一个计算圆柱体和圆锥体体积的函数,也许你会这样做:

    var PI = 3.1415926;
    var circleArea = function(theCircle) { return theCircle.radius*theCircle.radius*PI; }
    var cylinderVolume = function(theCylinder) {  return circleArea(theCylinder.circle)*theCylinder.height; }
    var taperedVolume = function(theTapered) {  return circleArea(theTapered.circle)*theTapered.height/3; }

    浏览器解释完这4条语句之后,你获得了想要的两个函数cylinderVolume和taperedVolume,但是请注意,你也获得了PI和circleArea,这并不是你想做的,换句话说,全局作用域被PI和circleArea“污染”了。也许前面一个脚本文件里已经定义了另一个PI=1.414,或者只有你掌握了计算圆面积的方法circleArea,你不想其他人也能方便地使用(话说回来既然用了JavaScript而不是什么COM技术,不管如何扭曲代码你的秘密总会被解析出来的,因为源码就是公开的嘛),你都应该将这两个家伙封装起来。下面的实现可能会比较好:

    function createFunction(){
        var PI = 3.1415926;
        var circleArea = function(theCircle) { …… }
        var cylinderVolume = function(theCylinder) {  …… }
        var taperedVolume = function(theTapered) {  …… }
        window.cylinderVolume = cylinderVolume;
        window.taperedVolume = taperedVolume;
    }
    createFunction();

    window是浏览器窗口对象,所有的“全局变量”都是window的属性。这个函数运行之后,window对象只获得了两个计算圆柱体和圆锥体体积的函数,在后面代码里可以方便地调用这两个函数。你看,PI和circleArea并没有随着createFunction定义的结束而被释放,它们被保存到一个由浏览器维护的地方,只要调用taperedVolume函数,就会使用到它们,这就是“闭包”的特性。

    如果仔细考虑,上面的实现还有问题,那就是污染了变量createFunction,那么也许使用匿名函数会更好。下面是最好的实现:

    function(){
        var PI = 3.1415926;
        var circleArea = function(theCircle) { …… }
        var cylinderVolume = function(theCylinder) {  …… }
        var taperedVolume = function(theTapered) {  …… }
        window.cylinderVolume = cylinderVolume;
        window.taperedVolume = taperedVolume;
    }();

    这样,利用函数体内局部变量是不可达的这一特点,就完成了对模块的封装,cylinderVolume和taperedVolume就是对外交流的接口。 也许你会说,直接把PI值和计算圆面积的逻辑写到计算体积的函数里不就行了?但是,当函数的规模足够大的时候,你一定不会想那么做的。

    至于利用对象的属性封装字段则很简单了,因为对象(名值对)本身就是用来模拟面向对象语言中的“对象”的,通过对象名来访问对象内部的属性,这是理所当然的。

    正则表达式

    正则表达式提供了非常灵活的字符串匹配方法,可想而知在表单验证之类的领域有着很强的应用。之前看犀牛书的时候一带而过,这次看书虽然不指望完全掌握,但我总想还是稍微整理一下吧。

    下面是正则表达式的一个简单的应用,返回1表示能够在索引(从0开始)为1的地方找到第一个匹配el。

    var text = “hello”;
    text.search(/el/);//->1

    正则表达式以一个斜杠开头,以一个斜杠结尾,中间的内容为匹配的内容。正则表达式可以通过通配符匹配字符串:

    “1a 2 3d”.search(/\s\d\s/); //->3 匹配到a后面的“空格2空格”

    还有一些常用通配符:

    通配符 释意
    \d  任意数字
    \w  任意单词
    \s  任意空字符:制表符、换行符、空格符
    \b   单词边界:标点符号,空格,字符串开头和结束
     .  任意不是换行符的字符

    正则表达式中,中括号"["和"]"之间的部分表示符合任意字符的匹配,星号和加号分别表示可以重复任意次数和重复至少一次:

    “abccxa”.search(/[xyz]/); //->4
    “abccxa”.search(/c*xa/); //->4

    字符串除了search方法,还有replace方法用以替换掉被匹配的字符串,还有match方法检测是否找到匹配。

    写在最后的话

    花了两天看完这本小书,有一些收获都基本写到了这两篇博文里面。也许有人会问:既然JavaScript有这么多缺点,OOP是模拟出来的,事件机制也是模拟出来的,甚至调用函数的时候连参数都不检查,那为什么还要学习它呢?我有这样的答案:首先,JavaScript的本质是简单的,在这种简单的基础之上构造抽象问题的思想却是值得学习的(当突然理解“闭包”的时候,我觉得设计者的思路真是妙绝了);其次,JavaScript作为一种“立竿见影”的语言,能帮助我做想做的事情:开发游戏——WebGL官方demo里面有个赛车游戏,简直太COOL了。

  • 相关阅读:
    我的知识库(4) java获取页面编码(Z)
    知识库(3)JAVA 正则表达式 (超详细)
    The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the associated filter. Struts
    某人总结的《英语听力的技巧 》,挺搞的
    我的知识库(5)java单例模式详解
    构建可扩展程序
    SerialPort (RS232 Serial COM Port) in C# .NET
    Python学习笔记——String、Sequences
    UI题目我的答案
    jQuery学习系列学会操纵Form表单元素(1)
  • 原文地址:https://www.cnblogs.com/yiyezhai/p/2778138.html
Copyright © 2011-2022 走看看