javascript语言精粹摘要

  • JavaScript中五种基本类型:string,number,boolean,null,undefined.还有一个对象类型object.
  • javascript只有一个数字类型。它在内部被表示为64位的浮点数,和Java的double数字类型一样。它没有分离出整数类型,所以1和1.0的值相同。
  • javascript在被创建的时候,Unicode是一个16位的字符集,所以javascript中的所有字符都是16位的。 
  • javascript中没有字符类型。要表示一个字符,只需创见仅包含一个字符的字符串即可。字符串是不可变的。一旦字符串被创建,就永远无法改变。
  • "\"(反斜线符号)是转义字符。
  • 下面列出的值被当做假:
  1. false
  2. null
  3. undefined
  4. 空字符串''
  5. 数字0
  6. 数字NaN
  • type运算符产生的值有'number'、'string'、'boolean'、'undefined'、'function'、'object'.

        

  • &&    1&&2==2    1||2==1
  • 对象字面量是一种可以方便的按指定规格创建新对象的表示法。
  1. 一个对象字面量就是包围在一对花括号中的零或多个'名/值'对。在对象字面量中,如果属性名是一个合法的JavaScript标识符且不是保留字,则并不强制要求用引号括住属性名。所以用引号括住'first-name'是必需的,但是否括住first_name则是可选的。
  • JavaScript包含一种原型链的特性,允许对象继承另一个对象的属性。正确的使用它能减少对象初始化是消耗的时间和内存。
  • for…in… hasOwnProperty

函数

  • 每个函数在创建时会附加两个隐藏属性:函数的上下文和实现函数行为的代码。每个函数对象在创建时也随配有一个prototype属性。它的值是一个拥有constructor属性且值即为该函数的对象。这和隐藏连接到Function.prototype完全不同。
  • 因为函数是对象,所以他们可以像任何其他的值一样被使用。函数可以保存在变量、对象和数组中。函数可以被当做参数传递给其他函数,函数也可以再返回函数。而且,因为函数是对象,所以函数可以拥有方法。
  • 函数的与众不同之处在于它们可以被调用。
  • 函数四个部分
  1. 保留字function
  2. 函数名(如果没有给函数命名,它被称为匿名函数)
  3. 包围在圆括号中的一组参数(这些参数的名称将被定义为函数中的变量。它们不像普通的变量那样将被初始化为undefined,而是在该函数被调用时初始化为实际提供的参数的值)
  4. 包围在花括号中的一组语句。这些语句就是函数的主体,它们在函数被调用时执行。

闭包

  • 一个内部函数除了可以访问自己的参数和变量,同时它也能自由访问把它嵌套在其中的父函数的参数与变量。通过函数字面量创建的函数对象包含一个连到外部上下文的连接。这被称为闭包。它是JavaScript强大表现力的来源。
 <script type="text/javascript">
        <!-- 在正常的脚本中,某个方法可以获取到外部的变量,或者全局变量 -->
        var num = 11;
        function func1(){
            console.log(num);
        }
        func1();

        <!-- 但是在外部是无法获取方法内部的局部变量的 -->
        function func2(){
            var num1 = 22;
            num2 = 33;
        }
        func2();
        <!--console.log(num1);  会报错!-->
        console.log(num2); <!--可以获取到num2的值,因为不适用var定义变量时,默认是全局变量 -->

        <!-- 那么如何在外部获取到内部的变量呢!javascript可以办到 -->
        function func3(){
            var num3 = 44;
            function func4(){
                return num3;
            }
            return func4;
        }
        var func = func3();
        console.log(func());
   </script>

       在外部无法获取到func3内部的局部变量,但是func3内部的局部方法func4却可以获取到,因此 返回一个func4的引用 ,这样在外部通过这个func4就可以获取到func3的内部变量。

  虽然是绕了一个圈子,但是在方法外部却通过这样一个手段获取到了内部的值。

    而这个方法内的局部方法func4就叫做闭包,按照很多书上的概念,这个方法搭建了方法内部与方法外部的桥梁,使得在外部也可以任意的获取到方法内部的资源。

  但是闭包会造成变量在内存中持久占用,因此会有一定的性能问题,最好不要轻易使用,即便使用也要在恰当的实际进行释放。

函数调用

  调用一个函数会暂停当前函数的执行,传递控制权和参数给新函数。除了声明时定义的形式参数,每个函数还接收两个附加的参数:this和arguments.

  • 参数this在面向对象编程中非常重要,它的值取决于调用模式。
  • 在JavaScript中一共有4种调用模式
  1. 方法调用模式
  2. 函数调用模式
  3. 构造器调用模式
  4. apply调用模式
  • 这些模式在如何初始化关键参数this上存在差异。
  • 函数运算符是跟在任何产生一个函数值的表达式之后的一对圆括号。
  • 当实际参数的个数与形式参数的个数不匹配时
  1. 实际参数的个数>形式参数的个数  超出部分会被忽略
  2. 实际参数的个数<形式参数的个数  缺失的值会被替换为undefined.
  3. 对参数值不会进行类型检查:任何类型的值都可以被传递给任何参数。

方法调用模式

  • 当一个函数被保存为对象的一个属性时,我们称它为一个方法。当一个方法被调用时,this被绑定到该对象。如果调用表达式包含一个提取属性的动作(即包含一个 . 点表达式或[subscript]下标表达式),那么它就是被当做一个方法来调用。

  //创建myObject对象。它有一个value属性和一个increment方法

  //increment方法接受一个可选的参数。如果参数不是数字,那么默认使用数字1

  var myObject = {

    value:0,

    increment:function(inc){

      this.value +=typeof inc ==='number'?inc:1;

    }

  };

  myObject.increment();

  document.writeln(myObject.value);//1

  

  myObject.increment(2);

  document.writeln(myObject.value);//3

  • 方法可以使用this访问自己所属的对象,所以它能从对象中取值或对对象进行修改。this到对象的绑定发生在调用的时候。这个“超级”延迟绑定使得函数可以对this高度复用。通过this可取得它们所属对象的上下文的方法称为公共方法。

  函数调用模式

  • 当一个函数并非一个对象的属性时,那么它就是被当做一个函数来调用的。  
  • 以此模式调用函数时,this被绑定到全局对象。(解决办法:如果该方法定义一个变量并给它赋值为this,那么内部函数就可以通过那个变量访问到this.按照约定,我把那个变量命名为that)

 构造器调用模式

  • JavaScript是一门基于原型继承的语言。这意味着对象可以直接从其他对象继承属性。该语言是无类型的。
  • 如果在一个函数前面带上new来调用,那么背地里将会创建一个连接到该函数的prototype成员的新对象,同时this会被绑定到那个新对象上。

  //创建一个名为Quo的构造器函数。它构造一个带有status属性的对象。

  var Quo = function(string){

    this.status = string;

  }

  //给Quo的所有实例提供一个名为get_status的公共方法

  Quo.prototype.get_status = function(){

    return this.status;

  }

  //构造一个Quo实例

  var myQuo = new Quo("confused");

  document.writeln(myQuo.get_status());//打印显示confused.

  • 一个函数,如果创建的目的就是希望结合new前缀来调用,那它就被称为构造器函数。按照约定,它们保存在以大写格式命名的变量里。如果调用构造器函数时没有在前面加上new,可能会发生非常糟糕的事情,既没有编译时警告,也没有运行时警告,所以大写约定非常重要。(不推荐这种构造器)

Apply调用模式

  • 因为JavaScript是一门函数式的面向对象的编程语言,所以函数可以拥有方法。
  • apply方法让我们构建一个参数数组传递给调用函数。它也允许我们选择this的值。apply方法接收两个参数,第一个是要绑定给this的值,第二个就是一个参数数组。

  //构造一个包含两个数字的数组,并将它们相加

   var array = [3,4];

   var sum = add.apply(null,array);//sum值为7

   //构造一个包含status成员的对象

   var statusObject = {

    status:'A-OK'

  }

  //statusObject并没有继承自Quo.prototype,但我们可以在statusObject上调用get_status方法,尽管statusObject并没有一个名为get_status的方法。

  var status = Quo.prototype.get_status.apply(statusObject); //status值为‘A-OK’

参数

  • 当函数被调用时,会得到一个“免费”配送的参数,那就是arguments数组。
  • 函数可以通过此参数访问所有它被调用时传递给它的参数列表,包括那些没有被分配给函数声明时定义的形式参数的多余参数。
  • 这使得编写一个无须指定参数个数的函数成为可能:

  //构造一个将大量的值相加的函数。

  //注意该函数的内部定义的变量sum不会与函数外部定义的sum产生冲突

  //该函数只会看到内部的那个变量

  var sum = function(){

    var i,sum =0;

    for(i=0;i<arguments.length;i+=1){

      sum+=arguments[i];

    }

    return sum;

  };

  document.writeln(sum(4,8,15,16,26,42));//108

  • 因为语言的一个设计错误,arguments并不是一个真正的数组。它只是一个“类似数组(array-like)”的对象。
  • arguments拥有一个length属性,但它没有任何数组的方法。

返回

  • 当一个函数被调用时,它从第一个语句开始执行,并在遇到关闭函数体的}时结束。然后,函数把控制权交还给调用该函数的程序。
  • return语句可用来使函数提前返回。当return被执行时,函数立即返回而不再执行余下的语句。
  • 一个函数总是会返回一个值。如果没有指定返回值,则返回undefined。
  • 如果函数调用时在前面加上了new前缀,且返回值不是一个对象,则返回this(该新对象)  

异常

  • JavaScript提供了一套异常处理机制。异常是干扰程序的正常流程的不寻常(但并非完全是出乎意料的)的事故。

  var add = function(a,b){

    if(typeof a!=='number'||typeof b!=='number'){

      throw{

        name:'TypeError',

        message:'add nedds numbers'

      };

    }

    return a+b;

  }

  • throw语句中断函数的执行。它应该抛出一个exception对象,该对象包含一个用来识别异常类型的name属性和一个描述性的message属性。你也可以添加其他的属性。
  • 该exception对象将被传递到一个try语句的catch从句:

  //构造一个try_it函数,以不正确的方式调用之前的add函数

  var try_it = function(){

    try{

      add("seven");

    }catch(e){

      document.writeln(e.name+':'+e.message);

    }

  }

  try_it();

扩充类型的功能

  • 我们可以通过给Function.prototype增加方法来使得该方法对所有函数可用:

  Function.prototype.method = function(name,func){

    this.prototype[name] = func;

    return this;

  }

  通过给Function.prototype增加一个method方法,我们下次给对象增加方法的时候就不必键入prototype这几个字符,省掉了一点麻烦。

  • 给Number.prototype增加一个integer方法来改善它。它会根据数字的正负来判断是使用Math.ceiling还是Math.floor.

  Number.method('integer',function(){

     return Math[this<0?'ceil':'floor'](this); 

  });

  document.writeln((-10/3).integer());//-3

  • JavaScript缺少一个移除字符串首尾空白的方法。这个小疏忽很容易弥补:

  String.method('trim',function(){

    return this.replace(/^\s+|\s+$/g,'');

  })

  document.writeln('"+"    neat     ".trim()+'"');

  • 通过给基本类型增加方法,我们可以极大地提高语言的表现力。
  • 因为JavaScript原型继承的动态本质,新的方法立刻被赋予到所有的对象实例上,哪怕对象实例是在方法被增加之前就创建好了。
  • 基本类型的原型是公共结构,所以在类库混用时务必小心。一个保险的做法就是只在确定没有该方法时才添加它。

  //符合条件时才增加方法

  Function.prototype.method = function(name,func){

    if(!this.prototype[name]){

      this.prototype[name] = func;

    }

    return this;

  }

递归

  • 递归函数就是会直接或间接地调用自身的一种函数。

继承

  • JavaScript是一门弱类型语言,从不需要类型转换。
  • 在基于类的语言中,对象是类的实例,并且类可以从另一个类继承。JavaScript是一门基于原型的语言,这意味着对象直接从其他的对象继承。

this

未完待续……

 

 


注:如若喜欢,欢迎转载,请在文章页面明显位置给出此文链接!
若您觉得这篇文章还不错请点击下右下角的推荐,有了您的支持才能激发作者更大的写作热情,非常感谢!

posted @ 2016-02-16 10:36  Caraxiong  阅读(206)  评论(0编辑  收藏  举报