1、对象是"key-value"对的集合,并拥有一个连到原型对象的隐形链接。

2、javascript中函数就是对象。

3、函数对象与普通对象的区别:

   a、 对象字面量产生的对象(非函数对象)连接到Object.prototype,函数对象则连接到Function.prototype(该原型本身连接到Object.prototype).

   b、函数对象在创建时会附加两个隐藏属性:函数的上下文和实现函数行为的代码。

   c、函数可以被调用

4、函数对象通过函数字面量来创建:

var add = function (a, b) {
    return a + b;
}

函数字面量包括四个部分:(1)保留字 function (2)函数名 <可选> (3)参数 (4)函数体


5、调用模式

    (1)方法调用模式:

           当一个函数被保存为一个对象的属性时,我们称它为一个方法。此时方法中的this 指向的是方法所属的

           对象。this到对象的绑定是发生在调用的时候。

     (2)函数调用模式:

           当一个函数非一个对象属性时,它就是当做一个函数来调用的。此时函数中的this被绑定到全局对象。

           这是语言设计上的错误。如果方法(注意是方法)里面定义了一个函数,那么函数中的this指向的是全局

           对象,而方法中的this指向的是方法所属的对象。

          解决方案如下:

myObject.double = function (){
    var that = this //解决方法
    
    //这是一个内部函数
    var helper = function(){
       //此时用that来指向myObject对象
       that.value = add(that.value, that.value);
    };
    helper();

}

      (3)、构造器调用模式:


    javascript是一门基于原型继承的语言。这意味着对象可以直接从其他对象继承属性。该语言是无类型的

  如果在一个函数前面带上new 来调用,那么背地里将会创建一个连接到该函数的prototype成员的新对象,同时

  函数体中的this指向的就是被新创建的对象。

var Quo = function (message){
    //此时的this还未绑定
    this.status = message;
}

Quo.prototype.get_status = function(){
    //此时this未绑定
    return this.status;
}

//构造一个对象,此时Quo函数体中的this指向的是myQuo对象
var myQuo =  new Quo("confused");

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

      (4)apply 调用模式

      因为函数也是对象,所以函数也可以拥有方法。(apply是函数对象被创建时附加的一个方法)apply接收两个参数,第一个是要绑定给this的值(其实就是函数调用时的上下文),第二个是一个参数数组。

var array = [3, 4];
//此时相当于直接调用 add(3,4);
var sum = add.apply(null, array); //sum为7

var statusObject = {
    status : 'A-OK';
}
//this只有在调用时才被绑定,而apply的第一个参数就是用来绑定this的
 var status = Quo.prototype.get_status.apply(statusObject)//status 为‘A-OK'

6、参数

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

var sum = function(){
    
    var i, sum = 0;
    
    for (i = 0; i < agruments.length; i +=1){
        sum += arguments[i];
    }
    
    return sum;

}

document.writeln(sum(1,2,3,4); //返回 10

注意:由于语言设计错误,arguments 并不是一个真正的数组。它只是一个”类似“数组的对象。arguments拥有一个length属性,但它没有数组的其他对象。


7、返回

一个函数总会有一个返回值。如果没有指定返回值,则返回一个undefined。

如果函数调用时在前面加上了 new 前缀 ,且返回值不是一个对象,则返回this(该新对象)

var Quo = function (message){
      //此时的this还未绑定
      this.status = message;
      var ob = {};
      //返回一个对象
      return ob;
}

//此时myObj 就是 {} 空对象
var myObj = new Quo("ss")

8、异常


javascript中的try 语句只会有一个捕获所有异常的catch代码块。如果你的处理手段取决于异常的类型,那么异常处理器必须检查异常对象的name属性来确定异常的类型。

var add = function(a, b){
    if (typeof a !== 'number' || typeof b !== 'number'){
          throw {
               name: 'Type error',
               message: 'add needs numbers'
          }
    }
    return a + b;

}


var try_it = function(){
  try {
      add("seven");
  }
  catch(e){
      document.writeln(e.name +':'+ e.message);
  }

}

9、扩充类型的功能

javascript 允许给语言的基本类型扩充功能。我们可以通过给Function.prototype增加方法来使得该方法对所有函数都有用。

例如:增加一个method方法,我们下次给对象增加方法时就不必键入prototype这几个字符了

Function.prototype.method = function(name, fun){
//不存在时才添加
 if(!this.prototype[name]){ 
   this.prototype [name] = fun;
 }
 return this;
}

//别忘了 Number 也是函数
Number.method('integer',function(){
    return Math[this < 0 ? 'cell' : 'floor'](this);
}

10、递归

      递归不用说了,说明一点,javascript本身不支持尾递归优化。