function add(x, y){ return x + y; }
上述函数定义以下:javascript
function
指出这是一个函数定义;add
是函数的名称;(x, y)
括号内列出函数的参数,多个参数以,
分隔;{}
之间的代码是函数体,能够包含若干语句,甚至能够没有任何语句。函数体内部的语句在执行时,一旦执行到return
时,函数就执行完毕,并将结果返回。
若是没有return
语句,函数执行完毕后也会返回结果,只是结果为undefined
。html
JavaScript的函数也是一个对象,函数名能够视为指向该函数的变量。所以,函数也能够像下面这样定义。java
var add = function (x, y){ return x + y; }
这种状况下,function (x, y){}
是一个匿名函数,它没有函数名。可是,这个匿名函数赋值给了变量add
,因此,经过变量add
就能够调用该函数。数组
调用函数时,按顺序传入参数便可。闭包
add(1, 2); // 3
关键字arguments
只在函数内部起做用。咱们经过arguments
能够得到调用者传入的全部参数。事实上,arguments
最经常使用于判断传入参数的个数。app
function add(x, y){ for(let i = 0; i < arguments.length; i++){ console.log(arguments[i]); } return x + y; } console.log(add(1,5)); // 1 5 6
在JavaScript中,用var
声明的变量是有做用域的。
若是一个变量在函数体内声明,则该变量的做用域是整个函数体。
若是两个不一样的函数各自声明了一个同名变量,那么这两个变量是相互独立的,互不影响。
因为JavaScript的函数能够嵌套,内部函数能够访问外部函数定义的变量,反过来则不行。
JavaScript的函数在查找变量时从自身函数定义开始,从"内"向"外"查找。
若是内部函数定义了与外部函数重名的变量,则内部函数的变量将"屏蔽"外部函数的变量。函数
JavaScript会把变量声明提高到顶部。post
function foo(){ console.log(x); // 不报错 var x = 'Hello'; } // 等同于 function foo(){ var x; console.log(x); x = 'Hello'; }
在一个对象中绑定函数,称为这个对象的方法。学习
var me = { name: '张三', birth: 1994, age: function(){ var y = new Date().getFullYear(); return y - this.birth; } }; console.log(me.age()); // 25
若是以对象的方法形式调用me.age()
,函数age()
的this
指被调用的对象me
。网站
apply
、call
、bind
var obj = {birth: 1990}; console.log(me.age.call(obj)); // 29 console.log(me.age.apply(obj)); // 29 let bind = me.age.bind(obj); console.log(bind()); // 29
apply
、call
和bind
这三个函数的做用是改变函数执行时的上下文,即改变函数运行时的this
的指向。
apply
和call
改变了函数的this
上下文后便执行该函数,bind
则返回改变了上下文后的一个函数。apply
和call
的第一个参数都是要改变上下文的对象,而call
从第二个参数开始以参数列表的形式展示,apply
把除了改变上下文对象的参数放在一个数组里面做为它的第二个参数。let arr1 = [1, 2, 10, 4]; //例子:求数组中的最值 console.log(Math.max.call(null, 1, 2, 10, 4)); // 10 console.log(Math.max.call(null, arr1)); // NaN console.log(Math.max.apply(null, arr1)); // 10
JavaScript的函数接收变量做为参数,而函数名能够视为指向该函数的变量。所以,一个函数能够接收另外一个函数做为参数。这种函数被称为高阶函数。
function add(x, y, f) { return f(x) + f(y); } console.log(add(-5, 6, Math.abs)); // 11
内置对象Array
提供了一些高阶函数:
map
reduce
filter
sort
every
find
findIndex
forEach
相关阅读:JavaScript Array 对象
高阶函数除了能够接受函数做为参数外,还能够把函数做为结果值返回。
/* function lazy_sum(arr) { var sum = function () { return arr.reduce(function (x, y) { return x + y; }); } return sum; } */ function lazy_sum(arr) { return function () { return arr.reduce(function (x, y) { return x + y; }); }; } var f = lazy_sum([1, 2, 3, 4, 5]); console.log(f()); // 15
在lazy_sum
函数中定义了函数sum
,sum
函数能够访问lazy_sum
函数的变量arr
(内部函数能够访问外部函数,参数能够看做函数中声明的变量)。当一个函数返回了一个函数后,相关的变量都保存在返回的函数中。
返回的sum
函数依然保持对lazy_sum
函数的做用域的引用,这个引用就叫做闭包。
注意:返回的函数没有当即执行,而是直到调用了f()
才执行。
使用闭包时要牢记一点是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
再看另外一个例子。
var buildMultiplier = function(x) { return function(y) { return x * y; } } var double = buildMultiplier(2); var triple = buildMultiplier(3); console.log(double(3)); // 6 console.log(triple(3)); // 9
参考: