要想学好 JavaScript 除了基本的 JavaScript 知识点外, 作为 JavaScript 的第一等公民函数, 我们要深入的了解函数的多变来源于参数的灵活多变和返回值的多变如果参数是一般的数据类型或一般对象, 这样的函数就是普通函数; 如果函数的参数是函数, 这就是我们所要知道的高级函数; 如果创建的函数调用另外一部分(变量和参数已经预置), 这样的函数就是偏函数
此外, 还有一点就是可选参数 (optional parameter) 的使用
函数的分类
普通函数
有函数名, 参数, 返回值, 同名覆盖示例代码如下:
- function add(a, b) {
- return a + b;
- }
匿名函数
没有函数名, 可以把函数赋值给变量和函数, 或者作为回调函数使用非常特殊的就是立即执行函数和闭包
立即执行函数示例代码如下:
- (function(){
- console.log(1)
- })()
闭包示例代码如下:
- var func = (function() {
- var i = 1;
- return function() {
- console.log(i);
- }
- })()
高级函数
高级函数就是可以把函数作为参数和返回值的函数如上面的闭包 ECMAScript 中也提供大量的高级函数如 forEach(), every(), some(), reduce()等等
偏函数
- function isType(type) {
- return function(obj) {
- return toString.call(obj) === "[object" + type + "]"
- }
- }
- var isString = isType('String');
- var isFunction = isType('Function');
相信, 研究过 vue.js 等常见库源码的同学不会陌生吧
箭头函数
箭头函数不绑定自己的 this,arguments,super 所以它不适合做方法函数, 构造函数, 也不适合用 call,apply 改变 this 但它的特点就是更短, 和解决匿名函数中 this 指向全局作用域的问题
- window.name = 'window';
- var robot = {
- name: 'qq',
- print: function() {
- setTimeout(function() {
- console.log(this.name);
- },
- 300)
- }
- };
- // 修改 1, 用 bind 修改 this 指向
- var robot = {
- name: 'qq',
- print: function() {
- setTimeout(function() {
- console.log(this.name);
- }.bind(this), 300)
- }
- };
- // 修改 2, 使用箭头函数
- var robot = {
- name: 'qq',
- print: function() {
- setTimeout(() = >{
- console.log(this.name);
- },
- 300)
- }
- };
想了解更多箭头函数可以看 MDN
函数的参数
传入明确的参数
- function add(a, b) {
- reutrn a + b;
- }
使用 arguments 对象
- function add() {
- var argv = Array.prototype.slice.apply(arguments);
- return argv.length > 0 ? argv.reduce(function(acc, v) { return acc+=v}): '';
- }
省略参数, 参数默认值
- function sub(a, b) {
- a = a || 0;
- b = b || 0;
- return a - b;
- }
对象参数
- var option = {
- width: 10,
- height: 10
- }
- function area(opt) {
- this.width = opt.width || 1;
- this.height = opt.height || 1;
- return this.width * this.height
- }
对象参数比较常见, 常出现在 jQuery 插件, vue 插件等中
可选参数
ES5 实现可选参数, 我们需要使用 arguments 使用指定范围的可选参数我们一般使用发对象参数, 写过 jQuery 等插件的应该印象深刻
ES6 中的函数参数
在 ES6 中, 参数默认值, 省略参数操作使用比较简便示例代码如下:
var area = (width=1, height=1) => width*height
在 ES6 中, 使用可选参数示例代码如下:
- var add = (...nums) => {
- var numArr = [].concat(nums)
- return numArr.reduce((acc, v) => acc += v)
- }
解构参数
- myFunc = function({x = 5,y = 8,z = 13} = {x:1,y:2,z:3}) {
- console.log(x,y,z);
- };
- myFunc(); //1 2 3 (默认值为对象字面量)
- myFunc({}); //5 8 13 (默认值为对象本身)
函数的返回值
函数的返回值为基本数据类型, 如字符串, 数字, Boolean,null,undefined 示例代码如下:
- function add(a, b) {
- return a + b
- }
函数的返回值为对象示例代码如下:
- function Robot(name) {
- this.name = name
- }
- Robot.prototype.init = function() {
- return {
- say: function() {
- console.log('My name is' + this.name)
- }.bind(this),
- dance: function(danceName) {
- console.log('My dance name is' + danceName)
- }
- };
- }
- var robotA = new Robot('A');
- robotA.init().say(); // "My name is A"
- var robotB = new Robot('B');
- robotB.init().say(); // "My name is B"
不管是写原生还是 jQuery 插件, 亦或其他插件, 这种情况都不少见更深入的了解可以参考 jQuery 源码
返回值为函数
这个我们最为熟悉的莫过于闭包具体可参考 老生常谈之闭包
参考文章
- JS: How can you accept optional parameters?
- Named and Optional Arguments in JavaScript
- How to use optional arguments in functions (with optional callback)
后续可能还会继续修改, 也欢迎各位批评指正有问题或者有其他想法的可以在我的 GitHub 上 pr
来源: https://juejin.im/post/5aa0ee4b6fb9a028c14a0a67