JavaScript 中的 Function 类型

版权声明:本文为博主原创文章,若转载请注明出处且不得删改。(如有错误请提出指正,部分文章会参考其他文章,已经表明参考出处,如有侵权请联系删除) https://blog.csdn.net/qq_34902437/article/details/81299583

参考 《JavaScript 高级程序设计》引用类型-Function

函数定义的三种方式

函数声明方式

    function method(){
        return 0;
    }

函数表达式方式

    var method = function(){
        return 0;
    }

构造函数方式

    var method = new Function("return 0");

理解 JavaScript 中没有重载

重载是指函数名相同,但是函数参数类型和个数不同
    function sum(n1,n2,n3){
        return n1+n2+n3;
    }

    function sum(n1,n2){
        return n1+n2;
    }

//  20
    alert(sum(10,10,10)); 
//  20
    alert(sum(10,10));
我们从函数对象的角度再来理解就很容易了。
    var sum = function(n1,n2,n3){
        return n1+n2+n3;
    }

// sum 的指向被覆盖了
    sum = function(n1,n2){
        return n1+n2;
    }

//  20
    alert(sum(10,10,10)); 
//  20
    alert(sum(10,10));

函数声明与函数表达式

函数声明和函数表达式在定义函数的时候并无差别,除了一点,函数声明提升
(function declaration hoisting)。
意思就是函数声明的方式定义函数,解析器会提前解析函数声明,而函数表达式
只有执行到代码段才解析。
// 20
    alert(sum(10,10));
    function sum(n1,n2){
        return n1+n2;
    }
    //报错
    alert(sum(10,10));
    var sum = function(n1,n2){
        return n1+n2;
    }
其实很容易理解,函数表达式实际上是对象指针,你还没有对象的时候怎么能指向它呢
?

函数作为值来使用

因为函数名本身就是变量,所以函数可以作为值来使用,也就是函数可以作为参数,以及作为另一个函数的返回结果。

函数作为参数

    var add = function(n1){
        return n1+10;
    }

    function sum(someFunction,n2){
         return someFunction(n2);
    } 

// 20
    alert(sum(add,10));

函数内部属性

arguments 的 callee(被叫者) 属性

callee 属性是一个指针,指向拥有 arguments 对象的函数。

我们用一个例子来说明

这是一个常见的阶乘函数。
    function jiecheng(num){
        if(num <= 1){
            return 1;
        }else{
            return num * jiecheng(num-1);
        }
    }

但问题是,这个函数耦合性太强,一旦改动,整个函数都会发生变化。

实现解耦
    function jiecheng(num){
        if(num <= 1){
            return 1;
        }else{
            return num * arguments.callee(num-1);
        }
    }

    // 函数指针发生改变
    var jiecheng2 = jiecheng;

this 属性

this 属性是当前执行环境的对象,如果是全局作用域,则是 window。
    window.color = 'black';
    // 定义一个变量对象
    var o = {color:"blue"};

    function sayColor(){
        alert(this.color);
    }

    // black
    sayColor();

    //为对象 o 新增一个 sayColor 的方法,该方法指向全局作用域下的 
    //sayColor() 
    o.sayColor = sayColor;
    // blue
    o.sayColor();

PS:函数名仅仅是一个包含指针的变量而已。例如有函数 say(),如果只是 say 的话,就是函数指针,say()才是执行函数。

caller 属性

caller 属性保留调用当前函数的函数的引用。

上面的定义很拗口,我们通过一个实际的例子来解释。

    function outer(){
        inner();
    }

    function inner(){
        alert(inner.caller);
    }

    outer();

    //outer()执行之后显示的是 outer()函数内部的源代码
    //所谓保存当前函数(inner)的函数(outer)的引用(指针)。

函数属性和方法

两个属性

length

length 返回的是函数命名参数的个数。
    function a(){

    }

    function b(n1){

    }
// 0
    alert(a.length);
// 1
    alert(b.length);

prototype

prototype 保存所有实例方法的真实所在。

方法

apply()和call()

两个方式都是在特定作用域调用函数。
apply(this,arguments)-参数1:运行函数作用域,-参数2:参数数组
call(this,arguments) -参数1:运行函数作用域,-参数2:参数对象

在参数上二者的区别是,apply 一般用于以数组的形式传递参数(参数多),而 call 则是一个个传递参数。

下面注重讲二者的意义-扩充作用域范围

    window.color = 'blue';
    var o = {color:'black'};

    function sayColor(){
        alert(this.color);
    }

    sayColor();

//blue,此时作用域为全局,this 自动转换为 window
    sayColor.call(this);
//blue,此时作用域为全局
    sayColor.call(window);
//black,此时作用域为对象 o,this 自动转换为 o 的this
    sayColor.call(o);

bind()

创建一个函数实例,this 的作用域会被绑定传递到使用 bind()的函数上
    var o = {color:'black'};

    function sayColor(){
        alert(this.color);
    }

    // 此时新函数 other 被指向 sayColor 函数且绑定了作用域 o
    var other = sayColor.bind(o);
    // black
    other();

猜你喜欢

转载自blog.csdn.net/qq_34902437/article/details/81299583