函数
函数
定义
一个处理事情的方法
作用
函数的意义在于封装
减少页面中冗余代码,提高代码重复利用率 ==》 '低耦合,高内聚'
函数的两部分
- 创建函数 function 函数名 (
形参) {…}
过程:开辟一个堆内存,把函数体的代码当做字符串存在堆中,把堆地址和变量相关联
注意:只创建函数,其实就是创建了存储一个字符串的堆,并没有实际作用 - 执行函数 函数名(
实参)
依赖条件:栈内存,供代码执行的上下文
作用:把创建的函数执行
注意:函数内部执行该函数会无限递归
var test = function abc() { abc() }
test(); // 进入递归,造成栈溢出
参数形式
形参:入口在JS函数中被称为形参,用来’存储执行函数时传递进来的信息’ ==》变量
实参:传递的具体值在JS函数中被称为实参 ==》具体传递的值
返回值
定义:JS函数的出口
作用:
1.基于 return 把变量的值暴露给外面使用
2.终止函数
注意:如果函数没有写 return,默认返回 undefined
创建函数的3种方式
- 函数声明
注意:if 括号中一定不能声明函数,会独自创建一个作用域
function test () { ... }
- 函数表达式
- 命名函数表达式
var test = function abc () { ... }
- 匿名函数表达式
var test = function () { ... }
- 箭头函数
let test = () => { ... }
- 函数构造器Function
注意:此方法不支持闭包,只能访问自身参数列表中的变量和全局变量
var test1 = new Function('a,b','console.log(a + b)')
//相当于 function test (a,b) { console.log(a + b) }
var test2 = new Function('console.log(a + b)')
//相当于 function test () { console.log(a + b) }
函数声明
函数命名规则
和变量的命名规则,基本一样
(1)不能以数字开头
(2)可以以字母, _ , $ 开头
(3)要有语义化:
==>指命名需要有意义
需要考虑到要结构化
并且,必须是英文,不能用中文(例: J_header)
(4)变量命名遵循:
==>小驼峰,首个字母小写,后面单词字母大写
例: function myFirstName(){}
(5)下划线命名法
function my_first_name(){}
(6)总之按所在公司开发规定来
(7)不能使用关键字,保留字(例:float 就是保留字)
命名函数表达式
函数作用域外部自动忽略函数名
会创建一个特定的辅助对象,将函数名作为属性存储,内部可以访问,并且是只读的
- name属性
var test = function abc() { ... }
console.log(test.name); // 'abc'
adc();// adc is not defined
- 函数内部可以
调用
var test = function abc() { abc() }
test();// Maximum call stack size exceeded 无限递归,造成栈溢出
特殊立即执行函数也是命名函数表达式
相关题目链接
var a = 1;
;(function a () {
a = 2;
console.log(a);//f a(){} 函数名是只读的,无法修改
delete a;
console.log(a);//f a(){} 函数名是只读的,无法删除
})
函数参数
形参与实参的映射关系
1.设定形参变量,但执行没有传递对应的值,则形参默认值为 undefined
2.形参只有两个,实参有三个,第三个并没有对应的形参接受(但是传递给函数了)
arguments
定义:函数内置实参集合 ==》 类数组
作用:包含了所有传递进来的实参信息,与是否定义形参无关
注意:ES6的箭头函数中没有arguments
function test() { console.log(arguments) }
test(1,2,3);//Arguments [1, 2, 3] 类数组
argument.length 传递实参的个数
function sum(a,b,c,d){
if(sum.length > arguments.length){
console.log('形参多了');
//sum.length 形参列表
}else if(sum.length < arguments.length){
console.log('实参多了');
}else{
console.log('相等');
}
}
argument.callee 参数所属的当前执行的函数作用域
function test(){ console.log(arguments.callee == test); }
test();//true
ES6的剩余运算符 …
定义:把传递进来的实参信息,都以数组的形式保存在args变量中
function test(...args) { console.log(args) }
test(1,2,3);// [1, 2, 3]
组合常规参数和剩余参数
一个常规参数,获取一个参数的值,剩余的参数由…argus接受
function test(a, ...args) { console.log(args) }
test(1,2,3);// [2, 3]
剩余参数和arguments的区别
1.剩余参数只包含没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参
2.arguments对象是一个类数组,而剩余参数是数组
立即执行函数
定义
函数声明以后立即执行该函数 ==》函数表达式
(function () { ... } ()); W3C
(function () { ... }) ();
特殊立即执行函数
带有函数名的立即执行函数 ==》命名函数表达式
函数作用域外部自动忽略函数名
会创建一个特定的辅助对象,将函数名作为属性存储,内部可以访问,并且是只读的
var a = 1;
;(function a () {
a = 2;
console.log(a);//f a(){} 函数名是只读的,无法修改
delete a;
console.log(a);//f a(){} 函数名是只读的,无法删除
})
使函数声明变成表达式的4种方法
- 赋值符号
- 括号
- 逻辑运算符 & | && ||
- 数学运算符 + - * /
// 赋值符号
var a = function () { ... }
a()
// 括号
(function () { ... } ())
// 逻辑运算符
0&function () { ... } ()
0|function () { ... } ()
1&&function () { ... } ()
0||function () { ... } ()
// 数学运算符
+function () { ... } ()
-function () { ... } ()
0*function () { ... } ()
0/function () { ... } ()
函数执行完出栈问题
// 其中test 函数执行完,没有产生闭包,直接出栈销毁
var test = function test(){
console.log('a');
}();
console.log(test);
// a undefined
高阶函数
概念
Higher-order function,一个函数就可以接收另一个函数作为参数的函数,像数组的map、reduce、filter这些都是高阶函数
// 简单的高阶函数
function add(x, y, f) {
return f(x) + f(y);
}
//用代码验证一下:
add(-5, 6, Math.abs); // 11
柯里化函数
概念
Currying,把接受多个参数的参数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术
作用
参数复用,提前返回和延迟执行
实现函数的柯里化
// 实现函数柯里化
function curry(fn) {
const fnArgsLength = fn.length // 传入函数的参数长度
let args = []
function calc(...newArgs) {
// 积累参数保存到闭包中
args = [...args, ...newArgs]
// 积累的参数长度跟传入函数的参数长度对比
if (args.length < fnArgsLength) {
// 参数不够,返回函数
return calc
} else {
// 参数够了,返回执行结果
return fn.apply(this, args.slice(0, fnArgsLength)) // 传入超过fnArgsLength长度的参数没有意义
}
}
return calc// 返回一个函数
}
function add(a, b, c) {
return a + b + c
}
// add(10, 20, 30) // 60
var curryAdd = curry(add)
var res = curryAdd(10)(20)(30) // 60
console.info(res)
实现计算累加
实现 fun(1).add(1).add(2).res() 为 4
const fn = (num) => {
return {
add: (n) => fn(num + n),
mine: (n) => fn(num - n),
take: (n) => fn(num * n),
divide: (n) => fn(num / n),
res: () => num
}
}
文章详细介绍了JavaScript中的函数,包括函数的作用、创建方式(声明、表达式、构造器)、参数形式、返回值、以及ES6的新特性如剩余参数。还讨论了函数的执行上下文,如arguments对象、函数命名规则、立即执行函数(IIFE)及其变种。此外,重点讲解了高阶函数的概念和柯里化技术,展示了如何实现柯里化函数。
5万+

被折叠的 条评论
为什么被折叠?



