美文网首页
第七章 Function类型补充

第七章 Function类型补充

作者: 尺间天涯 | 来源:发表于2019-02-01 17:53 被阅读0次

    在ECMAscript中,Function实际上是对象,每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,所以函数名实际上是一个指向函数对象的指针。

    声明方式

    1.普通声明方式

    function foo(a, b) {
        return a + b;
    }
    

    2.使用变量初始化函数

    let foo = function (a, b) {
        return a + b;
    }
    

    3.使用Function构造函数(不推荐,二次解析,第一次解析ECMA代码,再解析一次构造函数传入的字符串)

    let foo = new Function('a', 'b', 'return a + b');
    

    作为值的函数

    也就是函数本身就是变量,可以作为参数传给另外一个函数。

    栗子1:

    function add(a, b) {
        return a + b;
    }
    function sum(a, b) {
        return a + b;
    }
    console.log(sum(add(5, 5), 10)); 
    // 20 函数传递返回值
    

    栗子2:

    function add(a, b) {
        return a(b);
    }
    function sum(a) {
        return a + 10;
    }
    console.log(add(sum, 10));  
    // 20 函数做为值  而非返回值
    

    函数内部属性

    函数内部有两个特殊对象:argument和this,argument是类数组对象,包含传入函数中的所有参数,主要用途是保存函数参数。这个对象还有一个叫callee的属性,该属性是一个指针,指向这个argument对象的函数。

    1. arguments

    function foo(num) {
        if (num <= 1) {
            console.log(num);
            return 1;
        } else {
            console.log(num);
            return num * foo(num - 1); 
            // 4 * 3 * 2 * 1
        }
    }
    
    console.log(foo(4));
    // 4  3  2  1  24
    console.log(foo(1));
    // 1
    

    类似上面这种在函数内部调用自己的函数,也叫做递归。但是以上函数如果改变foo函数名位fun,内部函数名没有改变,则会报错,如果递归的代码很长,很难更改。所以,我们可以使用arguments.callee来代替。

    也就是将return num * foo(num - 1);改为return num * arguments.callee(num - 1);用callee调用自身,实现递归。

    2. this

    this是调用函数的作用域,当全局调用函数的时候,这时this指向window;

    window.color = 'red';
    //Window 对象表示浏览器中打开的窗口 表示全局 此处在window定义了一个全局变量color
    function sayColor() {
        return this.color;
        //作用链查找问题以后再说
    }
    console.log(sayColor());
    // red 访问全局变量color
    let obj = {
        color: 'blue',
        sayColor
        // ES6写法 此处用的是全局的sayColor函数
    };
    console.log(obj.sayColor());
    // blue 对象打点调用函数,this指向了调用函数的这个对象
    let foo = obj.sayColor;
    console.log(foo());
    // red
    

    函数属性和方法

    length属性

    表示函数形参个数

    function foo(a, b) {
        return a + b;
    }
    console.log(foo.length);
    

    prototype属性

    prototype也就是原型,保存所有实例方法。这个属性会在后面面向对象继续深入介绍。prototype下有两个方法:apply()和call(),每个函数都包括这两个非继承(后面再说)而来的方法。这两个方法的用途都在特定的作用域,调用函数。实际上等于设置函数this指向。

    apply

    function foo(a, b) {
        return a + b;
    }
    function fun(a, b) {
        return foo.apply(this, [a, b]);
    }
    function fun2() {
        return foo.apply(this, arguments);
    }
    console.log(fun(10, 10)); // 20
    console.log(fun2(10, 10)); // 20
    

    call

    var color = 'red';
    // let不可以的,以后再说吧
    let obj = {color: 'blue'};
    function foo() {
        return this.color;
    }
    console.log(foo(this));
    // red
    console.log(foo());
    // red
    
    console.log(foo.call(obj));
    // blue
    

    两者都可以改变函数的作用域,只是传参方式不一样。apply传数组,call直接传参。但是他们并不是上面这样用的,后面说面向对象再进行学习。还有一个绑定作用域的方法,叫做bind可以查阅一下。

    相关文章

      网友评论

          本文标题:第七章 Function类型补充

          本文链接:https://www.haomeiwen.com/subject/albdsqtx.html