美文网首页JavaScript学习笔记
JavaScript学习笔记3_函数也是数据

JavaScript学习笔记3_函数也是数据

作者: 菜出意料 | 来源:发表于2019-11-10 17:21 被阅读0次

    概述

    函数由函数名、形参列表和返回值构成,每次调用函数都会产生一个调用上下文,即this值。如果函数是对象的属性,就称其为对象的方法,当通过对象来调用时,该对象就是此次调用的上下文,也就是该方法的this值。如果函数用于初始化一个新创建的对象,那么被称为构造函数。

    函数的定义

    • function f() {return 1;}
    • var f = function() {return 1;}
      其中第二种定义方式通常被叫做函数标识记法(function literal notation).
      如果我们对函数使用typeof操作符,返回"function".
    function f() {}
    typeof f;
    
    image.png

    函数是一种数据,可将函数赋值给变量

    函数的特性

    • 它们包含的是代码
    • 它们是可执行的(可调用的)
    function sum(a, b) {
        return a+b;
    }
    var a = sum;
    a(1, 2);
    
    image.png

    匿名函数

    没有函数名的函数即为匿名函数

    用途

    • 回调函数
      由于函数可以赋值给变量,因此函数可以作为参数传递给其他函数,在函数体里调用执行.
    function add(a, b) {
        if (typeof b === "function") return a + b();
        return a + b;
    }
    add(1, function(){return 2;});
    
    回调示例

    在使用回调函数时,一般会将参数名命名为callback,function f(a, b, callbak){doSomething}

    • 自调函数
      函数定义后自行调用
    (function(name){console.log(name);})("小林")
    
    自调示例

    匿名函数的好处:不会产生全局变量,最适合执行一些一次性的或初始化任务.

    内部(私有)函数

    函数内部的函数即为内部(私有)函数

    function a() {
        function b() {
            console.log('b');
        }
        console.log('a');
        b();
    }
    a();
    
    内部函数

    返回函数

    函数也是一种数据,因此可以作为数据返回.

    function a() {
        return function() {
            console.log('return function');
        }
    }
    var b = a();
    b;
    b();
    
    image.png
    image.png

    返回的仅仅是函数的引用,因此需要使用b()调用内部函数.

    闭包

    闭包就是能够读取其他函数内部变量的函数,在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

    词法作用域

    在JavaScript中,每个函数都有一个自己的词法作用域.也就是说,每个函数在被定义时(非执行时)都会创建一个属于自己的环境(即作用域),请看以下示例:

    function f1(){var a=1; f2();}
    function f2(){console.log(a);}
    f1();
    
    image.png

    由于函数在定义时创建作用域,因此在f2函数创建时,无法访问到f1函数里的局部变量a.f1()和f2()之间不存在共享的词法作用域.

    闭包1

    function f() {
        var b = 'b';
        return function() {return b;}
    }
    var n = f();
    n();
    
    闭包1

    变量b是函数f的局部变量,在全局作用域中是不可见的,但是对函数f中的匿名函数是可见的.函数f在全局作用域中是可见的,因此我们在全局作用域中调用函数f,并将函数f的返回值赋值给全局变量n,从而生成一个可以访问函数f私有作用域的新全局函数.

    闭包2-循环中的闭包

    function f() {
        var a = [];
        for(var i=0; i<3; i++) {
            a[i] = function() {
                return i;
            }
        }
    
        return a;
    }
    var a = f();
    a[0]();
    a[1]();
    a[2]();
    
    错误的闭包

    我们创建的3个闭包,都指向了同一个局部变量i.闭包不会记录i的值,仅使用i的引用,因此当循环结束时,i的值为3,所以3个闭包的返回值相同,我们需要自调函数来解决此问题.

    function f() {
        var a = [];
        for(var i=0; i<3; i++) {
            a[i] = (function(x) {
                return function(){return x;}
            })(i);
        }
        return a;
    }
    var a = f();
    a[0]();
    a[1]();
    a[2]();
    
    image.png

    闭包示例

    迭代器

    function setup(x) {
        var i=0;
        return function() {
            return x[i++];
        };
    }
    var next = setup([1,2,3,4]);
    next();
    next();
    next();
    
    迭代器

    相关文章

      网友评论

        本文标题:JavaScript学习笔记3_函数也是数据

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