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

    醉心于Github上美妙的WebGL Demo之中,我试图努力学习JavaScript。我曾经囫囵吞枣地将那本犀牛书《JavaScript权威指南》看了一遍,无奈功力不够,对那些抽象的概念理解很有限。前一阵子亚马逊有买300减100活动,凑书的时候忽然想起之前汤姆大叔送的那本《JavaScript编程精解》评价不错,我当时手气不好(其实主要还是没有使用地精黑科技),没有抢到,就在亚马逊上买了一本。书拿到手后,发现其异乎寻常的薄,翻了两页感觉还不错,于是决定花点时间以此书为基础,再梳理一下JavaScript。

    值和变量

    值六种类型:number,string,Boolean,object,function,undefined,创建一个值的方法是使用直接量。值是由环境(浏览器)自动创建和维护的——当使用了值的直接量,环境就在内存中创建了这个值;当不再需要这个值的恰当的时候,这个值就被销毁。除此之外,没有可以影响或操纵值的方法。

    变量是值的引用,通过关键字var声明,由用户负责创建和维护。变量可以“抓取”值,却不能改变值:当为一个已赋值的变量赋新值的时候,实际上是创建了一个新值,并令该变量“抓取”之,而不是将新值填充到旧值中去。

    var x = 1;
    var add = function(a,b){return a+b;}
    var origin = {x:0,y:0};

    JavaScript中,数字是值,函数是值,对象也是值。上面三条语句的效果都是创建一个值,并声明一个对象引用该值,本质上没有区别。

    函数:作用域链、闭包

    JavaScript没有块级作用域,因此语句块中的定义的变量在语句块外是可见的。取而代之的是函数作用域,即在函数体内定义的变量在函数体外不可见,而函数体外定义的变量在函数体内可见。

    var s = “hello”;
    var t = s+” world”;
    function test(){
        var y = 1;
        t; //->“hello world”
    }
    y; //->undefined

    函数本质上也是值(我会反复强调这一点,因为只有理解了这一点,才能明白JavaScript为什么是解释型语言,为什么看起来和C++、C#相差那么大),在运行之前并不被环境所理解。浏览器像处理流一样运行JavaScript文本,事实上它根本不知道下一条语句是什么,更不会尝试“理解”该语言。因此JavaScript中的函数可以和定义函数的作用域中的其他变量直接交流,就像其他变量之间交流一样。上面的代码中,变量t和s有交流,函数变量test和t有交流,两者没有区别。在其他语言中,函数往往只通过参数和外界交流,而在JavaScript中函数可以和定义函数的作用域中的其他变量交流。有一点值得注意,就是函数中引用的函数外变量属于定义函数时的作用域,而不是调用函数时的作用域,下面的代码说明了这种令人费解的“闭包”特性——即,作用域并未随着函数定义语句结束而消失,函数在调用的时候仍然能够访问到函数定义时的作用域。

    function text(){
        var s=”local string”;
        var f = function(){
            return s;
        }
        return f;
    }
    var s = “global string”;
    text()();//->”local string”;

    既然函数也是值,那么将函数本身作为参数传入其他函数也很自然,对于只需要使用一次的函数仅使用匿名直接值也很自然。下面这样的写法很常见,也很方便,对于刚刚接触JavaScript的同学可能需要习惯一段时间。

    var theArray = [1,2,3,4];
    var theSum = 0;
    function forEach(array, action){
        if(array.length==undefined){
        throw “Input is not array.”
        }
        for(var i=0;i<array.length;i++){
            action(array[i]);
        }
    }
    forEach(theArray, function(n){
        theSum+=n;
    })

    上面的语句只有4句,浏览器对这4句语句顺序执行:1.定义一个数组theArray;2.定义一个值theSum;3.定义一个函数forEach(函数是值,所以这一句和之前两句没有区别,都是将值赋给一个变量)。4.调用函数forEach,将theArray和一个匿名函数传给forEach函数作为参数,该匿名函数影响了theSum值。

    函数内部有隐式的变量arguments,该变量是一个数组,顾名思义表示函数传入的参数。

    JavaScript说到底是一种脚本语言,最初的使命就是在一个特定的环境下,完成一项特定的有始有终的工作。原则上完成某个工作,只需要顺序编写语句就可以了。函数对工作进行了抽象,因此对于复杂工作,往往先嵌套地定义函数,然后调用之。上面说到,这里的函数依赖于当前作用域,更类似于“过程”。这样进行函数式的编程,最后程序的基本流程大致就变成了:定义全局变量、定义函数、调用函数这样的形式。

    对象和类:原型

    JavaScript中的对象本质上就是名值对。对象也是是object类型的值,可以赋给变量。对象可以通过对象直接量创建,也可以通过构造函数创建。

    var point1 = {x:1,y:0,z:0}
    var point2 = {x:0,y:1,z:0}
    function Point(theX,theY,theZ){
        this.x=theX;
        this.y=theY;
        this.z=theZ;
    }
    var point3 = new point(1,1,0);

    对象最重要的特征是继承。在其他面向对象编程语言中,编译器很轻松地知道,哪几个对象时同一类的,哪个类继承了哪个类,这在JavaScript中是由原型实现的。每一个对象都有一个原型对象,可以通过prototype字段访问。对象的原型对象就是对象构造函数的原型,比如point3.prototype就是Point.prototype,构造函数的原型对象在定义构造函数时也就生成了。构造函数是值,因此即使是函数体完全相同的构造函数,其值也是不一样的,其原型自然也就不一样。具有相同原型的对象,往往由相同的构造函数产生,这意味着这些对象是“同一类”,如同C#中同一类的多个实例一样。以对象直接量(即名值对,如point1和point2)赋值给对象的时候,实际上是隐式调用了构造函数Object(),因此这样的对象其原型是Object.prototype。当对象访问某个属性(即通过名查询值)的时候,首先查看对象本身是否是具有该值,然后是原型是否具有,然后是原型的原型是否具有……直到Object.prototype,只有该对象没有原型。

    具有相同原型的对象共享原型(这好像是废话),使得原型成为储存这些对象的公有成员的理想场所。比如,每个三角形对象不一样,但是计算三角形面积的方法是一样的,因此该方法应当定义在三角形对象的原型上,否则,对于每个三角形对象都会生成一个一模一样的函数——函数是值,正如我们之前强调的一样,函数会占用空间。

    function Triangle(thePoint1, thePoint2, thePoint3){……}
    Triangle.prototype.area = function(){……};
    var t=Triangle(point1, point2, point3);
    t.area(); //->0.5

    上面的代码使用了本节开始处代码的上下文,实际上point1和point2是同一类,point3是另外一类,这并不影响它们在Triangle函数中的表现,只需要能够提供x、y、z字段的对象都能正常工作。

    错误处理

    使用try…catch…finally块作错误处理,使用throw关键字抛出异常。异常由用户自己定义,如使用对象直接量,注意这里的type不是关键字,可以换成其他需要的字眼。

    throw {
    type:”ArgumentInvalidException”,
    message:”Input is not number.”
    }

    往往希望在某一层次只处理某一种类的异常,非该种类异常交由上层处理,可以使用捕捉异常、检查异常、不符合要求再抛出的方法。

    catch(e){
    if(e.type!=” ArgumentInvalidException”){
        throw e;
    }
    // 处理ArgumentInvalidException类型的异常
    }

    对功能函数编写测试函数,尽可能多地实验各种异常情况是好的习惯。

  • 相关阅读:
    typeof与instanceof
    TCP与UDP的区别
    const、let、var关键字
    基本通用的使用jdbc文件java代码连接数据库
    HTML知识点01
    ADO.NET基础02
    ADO.NET基础03
    数据库语法01
    数据库语法02
    Ubuntu16.4 内核降级
  • 原文地址:https://www.cnblogs.com/yiyezhai/p/2776169.html
Copyright © 2011-2022 走看看