JavaScript学习笔记3_函数也是数据
2019-11-10 本文已影响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();
迭代器