Skip to content

Files

Latest commit

f35a047 · Jul 13, 2017

History

History
309 lines (264 loc) · 7.57 KB

07. 函数 Function.md

File metadata and controls

309 lines (264 loc) · 7.57 KB

函数 Function

函数是一小段可重用的代码,可用于封装操作,计算结果并返回。函数最有趣的地方在于:它可以调用它自身,即递归

函数声明

以下是一个计算直角三角形斜边长的函数。

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 访问各个参数。

💡 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

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()
  • ...

函数 vs 方法

形如 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) {
  
} 

参考链接