JS之函数

下面是函数声明的例子:数组

function factorial(n) {
     if (n<=1) return 1;
     return n*factorial(n-1);
     }
  1. 函数声明语句一般出如今JS代码的最顶层,也能够嵌套在其余函数体内。但在嵌套时,函数声明只能出如今所嵌套函数的顶部。也就是说,函数定义不能出如今if语句、while循环或其余任何语句中,正是因为函数声明位置的这种限制,ES标准规范并无将函数声明归类为真正的语句。app

  2. 尽管函数声明语句和函数定义表达式包含相同的函数名,但两者仍然不一样。两种方式都建立了新的函数对象,但函数声明语句中的函数名是一个变量名,变量指向函数对象。和经过var声明变量同样,函数定义语句中的函数被显式地“提早”到了脚本或函数的顶部。所以它们在整个脚本和函数内都是可见的。使用var的话,只有变量声明提早了------------变量的初始化代码仍然在原来的位置。然而使用函数声明语句的话,函数名称和函数体均提早;脚本中的全部函数和函数中全部嵌套的函数都会在当前上下文中其余代码以前声明。也就是说,能够在声明一个js函数以前调用它。函数

  3. 构成函数主体的JS代码在定义之时并不会执行,只有调用该函数时,它们才会执行。有4中方式来调用JS函数:做为函数、做为方法、做为构造函数、经过它们的call()和apply()方法简介调用。this

  1.  函数调用------------ 对于普通的函数调用,函数的返回值成为调用表达式的值,若是该函数返回是由于解释器到达结尾,返回值就是undefined。根据ES3和非严格的ES5对函数调用的规定,调用上下文(this的值)是全局对象。然而,在严格模式下,调用上下文则是undefined。以函数形式调用的函数一般不使用this关键字。不过,"this"能够用来判断当前是不是严格模式。     
    spa

  2. var strict = (function(){return !this}());
  3. 方法调用--------------对方法调用的函数和返回值的处理,和上面描述的普通函数调用彻底一致。可是,方法调用和函数调用有一个重要的区别。即:调用上下文。函数体可使用关键字this引用该对象。和变量不一样,关键字this没有做用域的限制,嵌套的函数不会从它的函数中继承this。若是嵌套函数做为函数调用,其this值不是全局对象(非严格模式下)就是undefined(严格模式下)。例如:prototype

var o = {
        m: function() {
            var self = this;
            console.log(this == o);  //输出true,this就是这个对象o
            f();
            function f() {
                console.log(this ===o) //false,this的值是全局对象或undefined
                console.log(self === o) //true:self值外部函数的this值
                }
            }
            o.m();

4)构造函数的调用code

构造函数调用建立一个新的空对象,这个对象继承自构造函数的prototype属性。构造函数试图初始化这个新建立的对象,并将这个对象做为其调用上下文,所以构造函数可使用this关键字来引用这个新建立的对象。注意,尽管构造函数看起来像一个方法调用,它依然会使用这个新对象做为调用上下文。也就是说,在表达式new o.m()中,调用上下文并非o。构造函数一般不使用return关键字,它们一般初始化新对象,当构造函数的函数体执行完毕时,它会显式返回。在这种状况下,构造函数调用表达式的计算结果就是这个新对象的值。然而若是构造函数显式地使用return语句返回一个对象,那么调用表达式的值就是这个对象。若是构造函数使用return语句但没有指定返回值,或者返回一个原始值,那么这时将忽略返回值,同时使用这个新对象做为调用结果。对象

5) 间接调用
继承

JS中函数也是对象,和其余JS对象没什么两样。任何函数能够做为任何对象的方法来调用,哪怕这个函数不是那个对象的方法。咱们能够将call()和apply()看做是某个对象的方法,经过调用方法的形式来间接调用函数。call()和apply()的第一个实参是要调用函数的母对象,它是调用上下文,在函数体内经过this来得到它的引用。要想以对象o的方法来调用函数f()。能够这样使用:
作用域

f.call(o);
f.apply(o);

每行代码和下面代码的功能相似(假设对象o中预先不存在名为m的属性)。

o.m = f;
o.m();
delete o.m;

在ES5严格模式下,call()和apply()的第一个实参都会变为this的值,哪怕传入的实参数原始值甚至是null或undefined。在ES3和非严格模式ES5中,传入的null和undefined都会被全局对象代替,而其余原始值则会被相应的包装对象所代替。

对于call()来讲,第一个调用上下文实参以后的全部实参就是要传入待调用函数的值。好比,以对象o的方法的形式调用函数f(),并传入两个参数,可使用这样的代码:

f.call(o,1,2)

apply()方法和call()相似,但传入实参的形式和call()有所不一样,它的实参都放入一个数组当中:

f.apply(o,[1 2]);

若是一个函数的实参能够是任意数量,给apply()传入的参数数组能够是任意长度的。好比,为了找出数组中最大的数值元素,调用Math.max()方法的时候能够给apply()传入一个包含任意个元素的数组:

var biggest = Math.max.apply(Math, array_of_numbers);
相关文章
相关标签/搜索