JS函数
函数(方法):
通过function
关键字声明函数;函数必须被调用才能执行
1.无参函数
//name是自定义的函数名遵循变量的命名规则
function name(){
//函数体:
}
调用执行函数:
通过 函数名( ) 调用执行函数
2.有参函数
参数个数不受限制
function name(arg1, arg2, ...){
// arg1, arg2, ... 这是参数, 称之为形参, 本质是变量
// 函数体
}
调用执行函数:
通过 函数名(value1,value2,...) 调用执行函数value1,value2,...这是实参
3.函数的声明
无参函数
function print(){
// 进行相关的逻辑处理
console.log('hello world');
}
// 调用执行函数
print();
//hello world
有参函数
function koujue(a){
let res = a + 'world';
console.log(res);
}
//可以调用执行多次
koujue(100);//100world
koujue('hello');//helloworld
4.函数声明方式的区别
-
通过function关键字
function name(){}
// 关键字声明 :js优先解析函数和变量的声明 first(); function first(){ console.log('关键字function'); } first();
-
字面量形式 : 变量名就是函数名
let name = function(){}
// =========== 字面量形式 // var声明变量的存在变量提升 console.log(second); // undefined // 调用执行函数 // second(); // TypeError: second is not a function var second = function(){ console.log('字面量'); } second();
-
调用执行函数:
name();
-
一个函数可以被调用执行多次
两种方式的区别:
关键字声明的函数 可以在函数声明前后进行调用;
字面量形式声明的函数,只能在声明后调用
5.形参与实参
形参定义:
函数声明时传入的参数称之为形参
实参定义:
函数调用时传入的参数称之为实参
形参与实参之间的关系:
形参与实参是一一对应的
形参多实参少:
多余的形参默认值是undefined
function print1(a, b, c){
console.log(a, b, c);
}
print1(100);//100 undefined undefined
print1();//undefined undefined undefined
形参少实参多:
多余的实参会被自动忽略
function print1(a, b, c){
console.log(a, b, c);
}
print1(100,200,300,400);//100 200 300
print1();//undefined undefined undefined
6.匿名函数🔴
说明:没有指定函数名
示例:
//变量名就是函数名
let f = function(){
console.log("这是匿名函数");
}
//调用函数
f();// 这是匿名函数
//传入形参
let print = function(a, b){
console.log(a, b);
}
//传入实参
print('hello', 100);//hello 100
7.函数的应用(封装函数)
案例一:封装乘法口诀表
封装前:
for(let i = 1; i <= 9; i++){
for(let j = 1; j <= i; j++){
document.write(`${j} * ${i} = ${i * j}; `)
}
document.write('<br>')
封装后:
function FormulaTable(start, end) {
for (let i = start; i <= end; i++) {
for (let j = start; j <= i; j++) {
document.write(`${j} * ${i} = ${i * j}; `)
}
document.write('<br>')
}
}
FormulaTable(1, 9);
FormulaTable(10, 15);
FormulaTable(20, 30);
案例二:封装阶乘
function factorial(num){
let res = 1;
for(let i = 1; i <= num; i++){
res *= i;
}
console.log(res);
}
factorial(5);
factorial(10);
factorial(20);
案例三:求连续区间的阶乘之和
function factorialSum(start, end){
let sum = 0;
for(let i = start; i <= end; i++){
let res = 1;
for(let j = 1; j <= i; j++){
res *= j
}
sum += res;
}
console.log(sum);
}
factorialSum(5, 10)
factorialSum(1, 5)
8.作用域
作用域:分为全局作用域 和局部作用域 , es6 新增 块级作用域
全局作用域:
- 在函数的外边声明的变量拥有全局作用域
- window对象的属性和方法拥有全局作用域(window 通常被省略)
局部作用域:
在函数内声明的变量拥有局部作用域
⚠️在 if 或 for循环中使用var 声明的变量是全局变量 ;
⚠️如果是 let声明的变量,是块级作用域
if(3 > 2){
let number = 100; // 块级作用域
var str = 'hello world'; // 全局作用域
}
for(let i = 0; i < 5; i++) {
if(i == 3){
var count = 100; // 全局作用域
}
}
9.作用域链🔴
说明:变量的作用域
函数内使用或引用某个变量时,首先从函数内自身进行查找,找到则使用,没有则层层向上进行查找,直到找到为止,如果找到全局都没有找到,则报错
let num = '重磅消息';
function first(){
let num = 100;
function second(){
let num ='hello word';
function third(){
let num = '今天周五,明天周六';
console.log(num);
}
third();
}
second();
}
first();
10.函数的返回值 return
语法结构:
function 函数名(){
return 需要返回的结果;
}
函数名();
注意事项:⚠️
-
函数只是实现某种功能,最终的结果需要返回给函数的调用者函数名( ) 通过return实现
-
只要函数遇到return 就把后面的结果 返回给函数的调用者 函数名() = return后面的结果
-
return 后面的代码不会执行
-
return 只能返回一个值,如果用逗号隔开多个值,以最后一个为准
function fn(num1,num2){ return num1,num2; } conslog.log(fn(1,2));//2
-
求任意两个数的加减乘除结果
function getResult(num1, num2) { return [num1 + num2, num1 - num2, num1 * num2, num1 / num2]; } var re = getResult(8, 4); console.log(re); //[ 12, 4, 32, 2 ]
-
函数如果有return 则返回的是 return 后面的值,如果函数没有return 则返回undefined
function fn1(){ return 666; } console.log(fn1());// 666 function fn2(){ } console.log(fn2()); //undefined
-
break,continue,return 的区别
- break:结束当前的循环体(如for , while)
- continue : 跳出本次循环,继续执行下次循环(如for , while)
- return :不仅可以退出循环,还能够返回return语句中的值,同时还可以结束当前的函数体内的代码
示例:
function getResult(){
return 666;
}
console.log(getResult());
// 666
function getSum(num1,num2){
return num1 + num2;
}
console.log(getSum(5,6));//11
利用函数求任意一个数组中的最大值
function getArrMax(arr){
var max = arr[0];
for(var i = 1;i < arr.length; i++){
if(arr[i] > max){
max = arr[i];
}
}
return max;
}
var res = getArrMax([5,2,55,78,13,99]);
console.log(res);
11.函数作为返回值🔴
function print(){
let str = 'hello';
return function(){
console.log('这是返回值',str);
}
}
print()()
12.变量的提升机制
- 在函数内没有使用关键字声明的变量,拥有全局作用域
function first() {
var count = 200;
// 没有关键字声明str
str = 'hello world';
console.log(count);
}
first(); // 200
console.log(count); //报错
console.log(str);// hello world
- 变量的提升
function second(){
// 第一个拆分模块
// var score;
console.log(score);//undefined
// 使用关键字var声明的变量会存在变量提升机制
// 变量的声明会被提升到函数的最上边;变量的赋值还留在原来的位置
// 这一行代码被拆分两行代码执行
var score =98;
// 第二个拆分
// score = 98;
console.log(score);//98
}
second();
-
js 代码 按照从上到下的顺序依次执行
console.log(str); // let 声明的变量不存在变量提升的 // let str = 'hello'; // Cannot access 'str' before initialization var str = 'hello'; // undefined 变量提升 console.log(str);
13.函数对象的方法和属性🔴
函数对象的属性:
length
: 形参的个数
arguments
属性:是一个类数组对象;在函数的内部存在一个属性 arguments
;该属性是函数固有的
arguments.length
:获取的是实参的个数
function print(a,b){
// arguments 可以在函数内部直接访问使用
// 是一个类数组对象:本质是对象,单是可以通过下表访问值
console.log(arguments);
//[Arguments] { '0': 100, '1': 200, '2': 300, '3': 400 }
// 获取的是实参的个数
console.log(arguments.length);
// 4
// 通过下表访问值
console.log(arguments[0]);
// 100
}
print(100,200,300,400);
// length 属性获取形参的个数
let len = print.length;
console.log(len);// 2
函数对象的方法:
call()
:调用执行函数,修改this指向,传参是一一罗列的
apply()
:调用执行函数,修改this指向,传参是以数组的形式
bind()
: 返回的是一个新函数,方法的参数是一一罗列的
bind()
方法创建一个新的函数,在bind()
被调用时,这个新函数的 this 被指定为bind()
的第一个参数,而其余参数将作为新函数的参数,供调用时使用。返回一个原函数的拷贝,并拥有指定的 this 值和初始参数。
function third(str,n,m){
console.log('函数对象的方法',str,n,m);
}
third('hello',100,99);//函数对象的方法 hello 100 99
// call() 参数是一一罗列的
third.call(null,'在这里传参',999,666);//函数对象的方法 在这里传参 999 666
// apply() 参数是以数组的形式传递的
third.apply(null,['数组形式传递',500,'第三']);
//函数对象的方法 数组形式传递 500 第三
//bind()方法的参数是一一罗列的,返回的是一个新函数
third.bind()('在这里传参',999,666);
//函数对象的方法 在这里传参 999 666
函数对象的方法 call() apply() bind() 用法和区别
共同点:
都可以修改this 指向; 也可以传参;
不同点:
call()
方法的参数是一一罗列的(一个参数列表)
apply()
方法的参数是以数组的形式进行传递的(一个包含多个参数的数组。)
bind()
方法的参数是一一罗列的
call()
和 apply()
可以调用执行函数;bind()
方法返回的是一个新函数
14.Math
//求数组中的最大值和最小值
let arr = [23, 3245, 123, 440];
// let max = Math.max(10, 30, 50, 20);
let max = Math.max.apply(null, arr);
// let min = Math.min(10, 30, 50, 20);
let min = Math.min.apply(null, arr);
console.log(max, min);