JavaScript学习笔记

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

2019-11-10  本文已影响0人  菜出意料

概述

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

函数的定义

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();
迭代器
上一篇下一篇

猜你喜欢

热点阅读