JavaScript高级程序设计学习笔记——引用类型2Function类型(重要)

       函数是Function类型的实例,所以函数也是对象,从而函数也拥有方法,可用来增强其行为。这一点正是JS最有特色的地方)

函数名实际上是一个指向函数对象的指针,不会与某个函数绑定。

一、函数的定义

  • 函数声明语法:

        function sum(num1, num2){

            return num1 + num2;

        }//使用不带圆括号的函数名是访问函数指针,并非调用函数;

  • 函数表达式:

        var sum = function(num1, num2){

            return num1 + num2;

        };//注意:函数末尾有分号,就像声明其它变量一样;通过变量sum即可调用函数;

  • Function构造函数:

        var sum = new Function("num1" , "num2" , " return num1 + num2");//不推荐;前面是参数,最后是函数体;

        当声明了多个同名函数时,后面的函数覆盖前面的函数,没有重载发生,主要是因为ECMAScript没有函数签名。

       区分函数声明和函数表达式:解析器优先读取函数声明,并使其在执行任何代码之前可用(可访问);函数表达式,必须等到解析器执行到它所在的代码行才被执行,除了什么时候可以通过变量访问函数这点区别外,二者没有区别。当使用函数声明的形式来定义函数时,可将调用语句写在函数声明之前,而后者,这样做的话会报错。

        函数名本身即为变量,所以函数可以作为值来使用,可将一个函数作为参数传递给另一个函数(函数作为参数时后面不可加括号),也可将一个函数作为另一个函数的返回值。

二、函数内部属性

        函数内部有两个特殊对象:arguments和this。

  • arguments是一个类数组对象,包含着传入函数中的所有参数。该对象有一个名为callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。

function factorial(num){//阶乘函数

        if(num <=1){

        return 1;

        }else {

            return num * arguments.callee(num-1);//这样将函数的执行与函数名解耦合;

        }

}

  •  this,引用的是函数据以执行的环境对象。

window.color = "red";

        var o = { color: "blue" };

        function sayColor(){

            alert(this.color);

        }

        sayColor();     //red

        o.sayColor = sayColor;

        o.sayColor();   //blue

  • ECMAScript5规范了另一个函数对象的属性:caller,该属性中保存着调用当前函数的函数引用,如果是在全局作用域中调用当前函数,该值为null。

function outer(){

            inner();

        }

        function inner(){

            alert(arguments.callee.caller);

        }

        outer();//最后显示outer()函数的源代码,但要注意,不能为函数的caller属性赋值,否则导致错误

三、函数属性和方法

        函数是对象,因此也具有属性和方法,每个函数都包含两个属性:length和prototype。

  • length属性表示函数希望接收的命名参数的个数;

  • prototype属性时保存所有实例方法,该属性不可枚举,因此无法用for-in实现;诸如toString()、valueOf()等方法均保存在prototype名下,只不过是通过各自对象的实例访问;

        每个函数还包括两个非继承而来的方法:apply()、call()。

  • 二者的用途都是在特定作用域中调用函数,实际上等于设置函数体内的this对象值;

  • apply()接收两个参数:在其中运行函数的作用域,另一个是参数数组;

  • call()接收两个参数:在其中运行函数的作用域,另一个是传递给函数的参数逐个列出

  • 二者最强大的用途是可以扩充函数赖以运行的作用域,且对象不需要与方法有任何耦合关系

window.color = "red";

        var o = { color: "blue" };

        function sayColor(){

            alert(this.color);

        }

        sayColor();            //red

        sayColor.call(this);   //red

        sayColor.call(window); //red

        sayColor.call(o);      //blue
  • bind()是ECMAScript5定义的,创建一个函数的实例,其this值会被绑定到传给bind()函数的值

window.color = "red";

        var o = { color: "blue" };

        function sayColor(){

            alert(this.color);

        }

        var objectSayColor = sayColor.bind(o);

        objectSayColor();   //blue

四、函数返回值

  • 即使函数确实有值,也不必明确地声明它。该函数只需要使用 return 运算符后跟要返回的值即可。

  • 与在 Java 中一样,函数在执行过 return 语句后立即停止代码。因此,return 语句后的代码都不会被执行。

  • 如果函数无返回值,那么可以调用没有参数的 return 运算符,随时退出函数。它真正返回的值是 undefined。

五、函数的执行

       ( function(){…} )()和( function (){…} () )是两种javascript立即执行函数的常见写法。

       匿名函数适合用来定义再整个脚本里只出现一次的函数:匿名函数没有名字,只能在哪里定义,在哪里使用。


  • 方式1,调用函数,得到返回值。强制运算符使函数调用执行

(function(x,y){

    alert(x+y);

    returnx+y;

}(3,4));

  • 方式2,调用函数,得到返回值。强制函数直接量执行再返回一个引用,引用再去调用执行

(function(x,y){

    alert(x+y);

    returnx+y;

})(3,4);

这种方式也是很多库爱用的调用方式,如jQuery,Mootools。


  • 方式3,使用void

void function(x) {

      x = x-1;

      alert(x);

}(9);

  • 方式4,使用-/+运算符

-function(x,y){

    alert(x+y);

    returnx+y;

}(3,4);

+function(x,y){

    alert(x+y);

    returnx+y;

}(3,4);

--function(x,y){

    alert(x+y);

    returnx+y;

}(3,4);

++function(x,y){

    alert(x+y);

    returnx+y;

}(3,4);

  • 方式5,使用波浪符(~)

~function(x, y) {

    alert(x+y);

   returnx+y;

}(3, 4);

  • 方式6,匿名函数执行放在中括号内

[function(){

   console.log(this) // 浏览器得控制台输出window

}(this)]

  •  方式7,匿名函数前加typeof

typeoffunction(){

   console.log(this) // 浏览器得控制台输出window

}(this)

  • 方式8,匿名函数前加delete

deletefunction(){

   console.log(this) // 浏览器得控制台输出window

}(this)

  • 方式9,匿名函数前加void

void function(){

   console.log(this) // 浏览器得控制台输出window

}(this)

  • 方式10,使用new方式,传参

newfunction(win){

   console.log(win) // window

}(this)

  • 方式11,使用new,不传参

newfunction(){

    console.log(this) // 这里的this就不是window了

}

  • 方式12,逗号运算符

1, function(){

    console.log(this) // window

}();

  • 方式13,按位异或运算符

1^function(){

    console.log(this) // window

}();

  • 方式14,比较运算符

1>function(){

    console.log(this) // window

}();

最后看看错误的调用方式

function(x,y){

    alert(x+y);

    returnx+y;

}(3,4);



你可能感兴趣的:(学习笔记)