1. 函数

1.1 定义函数

function add(x, y){
return x + y;
}

上述函数定义如下:

  • 关键字function指出这是一个函数定义;
  • add是函数的名称;
  • (x, y)括号内列出函数的参数,多个参数以,分隔;
  • {}之间的代码是函数体,可以包含若干语句,甚至可以没有任何语句。

函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回。

如果没有return语句,函数执行完毕后也会返回结果,只是结果为undefined

JavaScript的函数也是一个对象,函数名可以视为指向该函数的变量。因此,函数也可以像下面这样定义。

var add = function (x, y){
return x + y;
}

这种情况下,function (x, y){}是一个匿名函数,它没有函数名。但是,这个匿名函数赋值给了变量add,所以,通过变量add就可以调用该函数。

1.2 调用函数

调用函数时,按顺序传入参数即可。

add(1, 2); // 3

关键字arguments只在函数内部起作用。我们通过arguments可以获得调用者传入的所有参数。事实上,arguments最常用于判断传入参数的个数。

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

2. 作用域

2.1 概述

在JavaScript中,用var声明的变量是有作用域的。

如果一个变量在函数体内声明,则该变量的作用域是整个函数体。

如果两个不同的函数各自声明了一个同名变量,那么这两个变量是相互独立的,互不影响。

由于JavaScript的函数可以嵌套,内部函数可以访问外部函数定义的变量,反过来则不行。

JavaScript的函数在查找变量时从自身函数定义开始,从"内"向"外"查找。

如果内部函数定义了与外部函数重名的变量,则内部函数的变量将"屏蔽"外部函数的变量。

2.2 变量提升

JavaScript会把变量声明提升到顶部。

function foo(){
console.log(x); // 不报错
var x = 'Hello';
} // 等同于 function foo(){
var x;
console.log(x);
x = 'Hello';
}

3. 方法

在一个对象中绑定函数,称为这个对象的方法。

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

3.1 applycallbind

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

applycallbind这三个函数的作用是改变函数执行时的上下文,即改变函数运行时的this的指向。

  • applycall改变了函数的this上下文后便执行该函数,bind则返回改变了上下文后的一个函数。
  • applycall的第一个参数都是要改变上下文的对象,而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

5. 高阶函数

5.1 概述

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 对象

5.2 闭包

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。

/*
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函数中定义了函数sumsum函数可以访问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

参考

最新文章

  1. jQuery校验
  2. ready与onload的性能
  3. 构建 ARM Linux 4.7.3 嵌入式开发环境 —— U-BOOT 引导 Kernel
  4. Python数据分析之numpy学习
  5. 我的WCF之旅(3):在WCF中实现双工通信
  6. UIView -&gt; image &amp; 本地时间获取
  7. nginx自定义模块编写-根据post参数路由到不同服务器
  8. Hibernate之1-N关联映射
  9. MEF初体验之五:Lazy Exports
  10. IK分词器 IKAnalyzer 简单demo
  11. 安卓---高德地图API应用
  12. 快看Sample代码,速学Swift语言(1)-语法速览
  13. 总结Oracle8i 的UNDO表空间损坏(ORA-01092及ORA-00600【4193】)情况下的数据库不完全恢复的经历
  14. 解决前端页面a标签嵌套a标签bug
  15. APIO dispatching
  16. (NO.00001)iOS游戏SpeedBoy Lite成形记(二)
  17. Eclipse中查看JDK类库源代码
  18. js--sort()排序方法的使用--(笔记)
  19. equals&amp;&amp;==的使用
  20. 解决 Mac 的 Terminal 中,Java 乱码的问题

热门文章

  1. web 部署专题(零):web相关概念以及原理
  2. 【JS代码压缩】使用YUI Compressor对js文件进行压缩处理
  3. C#根据反射动态创建ShowDoc接口文本信息
  4. bzoj3196Tyvj1730二逼平衡树
  5. 虚拟DOM Vitural DOM Tree
  6. Web Security Academy ___XXE injection___Lab
  7. MySQL数据库---表的操作
  8. 在ASP.NET中,&lt;%= %&gt;和&lt;%# %&gt;有什么区别
  9. linux nginx 部署多套服务(以react包为例)
  10. Pyramid attention networks for image restoration