函数是一小段可重用的代码,可用于封装操作,计算结果并返回。函数最有趣的地方在于:它可以调用它自身,即递归。
以下是一个计算直角三角形斜边长的函数。
function xc(a, b) {
var a2 = a * a;
var b2 = b * b;
return Math.sqrt(a2 + b2); // Math.sqrt() 用于开平方
}
💡 勾股定理:平面上的直角三角形的两条直角边的长度(古称勾长、股长)的平方和等于斜边长(古称弦长)。
> xc(3, 4)
→ 5
> xc(6, 8)
→ 10
函数可以有参数也可以没有参数。
> new Date().getFullYear()
→ 2017
> Math.abs(-3)
→ 3
值得注意的是,有时候参数是可选的。
> ['HTML', 'CSS', 'JavaScript'].join()
→ "HTML,CSS,JavaScript"
> ['HTML', 'CSS', 'JavaScript'].join(' ')
→ "HTML CSS JavaScript"
调用函数时如果没有给参数赋值,则参数值是 undefined
。使用 =
可以给参数设置默认值。ES6
以下是一个计算圆面积的函数。
function area(r, π = 3.14) {
return π * r * r;
}
> area(2)
→ 12.56
> area(2, Math.PI)
→ 12.566370614359172
设置默认参数值の复古风格
function area(r, π) {
π = π || 3.14;
return π * r * r;
}
在函数内部可通过 arguments
对象访问参数列表,在参数个数不确定时一般通过遍历 arguments
访问各个参数。
💡 arguments
是一个貌似数组的对象,具有 length
属性,可以通过下标访问元素,但没有数组的方法。
以下函数 sum()
接受任意数目的(数字)参数,并返回这些参数的和。
function sum() {
var result = 0;
for (var i = 0; i < arguments.length; i++) {
result += arguments[i];
}
return result;
}
> sum(1, 2, 3, 4, 5)
→ 15
在函数中使用 return
返回值。
- 若函数中没有
return
或只是通过return;
结束函数的执行,则函数的返回值是undefined
。 - 若函数中包含
return
且有具体的返回值,如return a + b;
,则函数的返回值是return
后面的表达式的值。
return
和返回值之间添加换行。
当返回的表达式较长时,你可能会想把它放到下一行。以下代码会使函数返回 undefined
,
return
(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15);
因为它等价于以下代码。
return;
(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15);
函数可以作为值给变量赋值。
var xc = function(a, b) {
return Math.sqrt(a * a + b * b);
};
调用方式与函数声明方式一致。
> xc(3, 4)
→ 5
> xc(6, 8)
→ 10
匿名函数在 JavaScript 中被广泛使用,尤其是在监听浏览器事件时。
// 浏览器窗口大小改变时,输出窗口宽高。addEventListener 用于添加事件监听器。
window.addEventListener('resize', function() {
console.log(`当前窗口宽度:${window.innerWidth}px 高度:${window.innerHeight}px`);
});
IIFE 全称 Immediately-Invoked Function Expression,译作立即执行の函数表达式。
(function() {
var keyframes = [
{ transform: 'translateY(-180px)' },
{ transform: 'translateY(0)' }
];
var options = {
duration: 600,
easing: 'cubic-bezier(0.565,1.65,0.765,0.88)',
};
document.body.animate(keyframes, options);
})();
IIFE 还有以下几种常见写法,只要掌握其中一种就 🆗 了。
(function() {
console.log('立即执行🚀');
}());
!function() {
console.log('立即执行🚀');
}();
+function() {
console.log('立即执行🚀');
}();
在函数内声明的变量仅在函数内部可见。
function greet() {
var message = '早';
console.log(message);
}
> greet()
早
→ undefined
> message
× Uncaught ReferenceError: message is not defined
at <anonymous>:1:1
函数可以访问其作用域以外的变量。
var name = '小波先生';
function greet() {
var message = `早!${name}`;
console.log(message);
}
> greet()
早!小波先生
→ undefined
所有函数外的顶层环境被称为全局作用域,定义在全局作用域的值可以在任何地方被访问。
在函数内部可以定义其他函数并调用。💡 函数声明会被提升(Hoist)到所处作用域的顶端。
function greet() {
var name = '小波先生';
morning();
evening();
function morning() {
console.log(`Good morning, ${name}!`);
}
function evening() {
console.log(`Good evening, ${name}!`);
}
}
> greet()
Good morning, 小波先生!
Good evening, 小波先生!
→ undefined
isNaN()
alert()
prompt()
confirm()
console.log()
console.warn()
console.error()
- ...
形如 console.log()
的函数更准确的称谓是方法。定义在对象(Object)内部的函数称为方法。
💡 方法的显著特征是调用时前面有 .
。
箭头函数(Arrow Function) ES6
比函数表达式更简洁且以词法方式绑定 this
。箭头函数总是匿名的。
> var square = x => x * x;
→ undefined
> square(3)
→ 9
> ['?', '!', '.'].map((m, i) => m.repeat(i + 1))
→ ["?", "!!", "..."]
- 编写以下函数
area()
,并使用ES6
的方式给height
设置默认值。
/**
* 给定长方形的宽和高,计算其面积并返回。
* 若 宽 === 高,则只需要传入宽的值。
* @param {number} width 宽
* @param {number} height 高
* @return {number}
*/
function area(width, height) {
}
- 编写以下函数
max()
/**
* 输入任意数目的数字参数,返回其中最大的数字。
* @return {number}
*/
function max() {
}
- 编写以下函数
pow()
/**
* 给定数字 x,返回 x 自乘 n 次的结果。
* @param {number} x
* @param {number} n - 正整数
* @return {number}
*/
function pow(x, n) {
}
- 编写以下函数
appearances()
/**
* 计算在某段文本 content 中出现某个特定字符串 search 的次数。
* @param {string} content - 被搜索的文本内容
* @param {string} search - 查找的字符串
* @return {number} 字符串 search 在 content 中出现的次数,没有则返回 0。
*/
function appearances(content, search) {
}
- 勾股定理
- https://javascript.info/closure
- https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions
- https://developer.mozilla.org/en-US/docs/Web/API/Element/animate
- https://en.wikipedia.org/wiki/Immediately-invoked_function_expression
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function
- https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Functions