javaScirpt学习第五章(函数)-第一部分
javaScirpt学习第五章(函数)-第一部分
- JavaScript函数是一段可重复调用的代码块,用于执行特定任务。通过function关键字或箭头函数等语法定义,
- JavaScript函数可以接收参数并返回值 ,是实现代码复用和模块化的基础单元
一、函数基本概念
函数(Function)
- 函数也是一个对象
- 它具有其他对象所有的功能
- 函数中可以存储代码,且可以在需要时调用这些代码
语法:
function 函数名(){
语句…
}调用函数:
- 调用函数就是执行函数中存储的代码
- 语法:
函数对象()使用typeof检查函数对象时会返回function
使用方式
<script>// 创建一个函数对象,函数实际上也是对象function fn() {console.log('你好!');console.log('hello');console.log('萨瓦迪卡');}// 调用fn函数fn(); // 函数的意义在于,如果我有多个地方需要使用,如果发生变动,我只需要改一个地方即可,不会改漏掉console.log('测试函数调用2次===============》》》》》》》》开始')fn();fn();console.log('测试函数调用2次《《《《《《《==================结束')</script>
二、函数的创建方式
函数的定义方式:
1.函数声明
function 函数名(){
语句…
}
2.函数表达式
const 变量 = function(){
语句…
}
3.箭头函数
() => {
语句…
}
使用方式
<script>// 方式1 function fn1() {console.log('函数声明所定义的函数')}// 方式2 const fn2 = function() {console.log('函数表达式')}// 方式3 const fn3 = () => {console.log("箭头函数....")}// 方式3 的简写方式,里面只有一行代码,大括号可以省略不写const fn4 = () => console.log('我是箭头函数简写方式!')const checkTypeOf = (obj) => {console.log('类型:',typeof obj)}// 测试函数的类型 都为 FunctioncheckTypeOf(fn1);checkTypeOf(fn2);checkTypeOf(fn3);checkTypeOf(fn4);// 调用函数fn1();fn2();fn3();fn4();</script>
三、函数传参
形式参数
- 在定义函数时,可以在函数中指定数量不等的形式参数(形参)
在函数中定义形参,就相当于在函数内部声明了对应的变量但是没有赋值实际参数
- 在调用函数时,可以在函数的()传递数量不等的实参
实参会赋值给其对应的形参
参数:
1.如果实参和形参数量相同,则对应的实参赋值给对应的形参
2.如果实参多余形参,则多余的实参不会使用
3.如果形参多余实参,则多余的形参为undefined
- 参数的类型
JS中不会检查参数的类型,可以传递任何类型的值作为参数
1.函数声明
function 函数名([参数]){
语句…
} 2.函数表达式
const 变量 = function([参数]){
语句…
} 3.箭头函数
([参数]) => {
语句…
}
使用方式
<script>// 普通函数没有传参数,我们计算两个值的和function sum1() {// 我们看到这个值有很大的局限性,不能自定义我们给定的参数计算console.log(12232 + 42323);}// 1、函数声明方式 定义形参,只需要定义个数即可 function sum2(num1,num2) {console.log('num1 + num2 = ',num1 + num2)}// 调用函数声明方式sum2(45343,76644);//um1 + num2 = 121987// 箭头函数const sum3 = (num1,num2) => console.log('num1 + num2 = ',num1 + num2);// 箭头函数调用sum3(45343,76644);//um1 + num2 = 121987//非正常值,因形参不会限制传入的数值类型,当我们传入的是非数字时候计算结果// 1、明明形参是2个,我们只传了一个sum3(1);//num1 + num2 = NaN// 非数字类型,字符串sum3(1,'你好娃');//num1 + num2 = 1你好娃// null sum3(null,11);//num1 + num2 = 11// bigint类型sum3(12,11n);//直接报错</script>
四、箭头函数的参数
箭头函数是es6新贴出来的,写起来简洁; () => 方式
使用方式
<script>const fn = (a, b) => {console.log("a =", a);console.log("b =", b);}//当箭头函数只有一个参数时候,可以省略const fn2 = a => {console.log('我是函数fn2,a=',a)}//执行函数fn(1,3);fn2(222)//我是函数fn2,a= 222//定义参数时,可以为参数指定默认值,// 默认值,在没有对应的实参时候生效const fn3 = (a = 10, b = 20, c = 30) => {console.log('a = ',a,",b = ",b,",c = ",c);console.log('b = ',b);console.log('c = ',c);}fn3(1,2);//a = 1 ,b = 2 ,c = 30</script>
五、对象传参
我们在传参里面传一个对象,如 {name:‘李四’}
使用方式
<script>function fn(a) {//console.log('a=',a)//console.log(a.name)// 修改变量时,只会影响当前的变量//a = {}a.name = '沙和尚';// 修改对象时,如果有其他变量指向该对象则所有指向该对象的变量都会受到影响console.log(a)}let obj = {name: '悟空'}// 传递实参时,传递并不是变量本身,而是变量中存储的值fn(obj)console.log('obj',obj)// 第二种方式let obj2 = {name:'唐僧'};// 函数每次调用,都会重新创建默认值function fn2(b = {name:'猪八戒'}) {console.log("b = ",b);b.name = '妖怪'console.log("b2 = ",b);}fn2(obj2);// 唐僧 妖怪fn2(obj2);// 妖怪 妖怪fn2();// 猪八戒 妖怪fn2();// 猪八戒 妖怪</script>
六、函数作为参数
<script>function fn(a) {console.log('a = ',a)//执行a 函数方法 a();}//创建函数function fn2() {console.log('我是函数 fn()')}// 调用fn(fn2);// 是函数 fn()// 使用匿名函数fn(function() {console.log('我是匿名函数,我被执行了')})// 使用箭头函数fn(() => console.log('我是箭头函数====》'))</script>
七、函数的返回值
在函数中,可以通过return关键字来指定函数的返回值
- 返回值就是函数的执行结果,函数调用完毕返回值便会作为结果返回
任何值都可以作为返回值使用(包括对象和函数之类)
如果return后不跟任何值,则相当于返回undefined
如果不写return,那么函数的返回值依然是undefined
return一执行函数立即结束
使用方式
<script>function sum(a,b) {//console.log( a + b);//计算完成后,将计算的结果返回而不是直接打印return a + b;}// 当设置了返回值的时候,我们需要接收一下,否则什么就没有let result = sum(3,3333);console.log('result = ',result)function fn1() {//当我们什么都不写看返回什么 undefined// return ;// 返回的是空 undefined// return {name: '八戒'}// {"name": "八戒"}alert(123)returnalert(456);// 这一行不会执行}console.log(fn1())</script>
八、箭头函数返回值
箭头函数的返回值可以直接写在箭头后
- 如果直接在箭头后设置对象字面量为返回值时,对象字面量必须使用()括起来
使用方式
<script>const sum = (a,b) => a + b;console.log('sum函数执行结果 = ',sum(435,788737));//sum函数执行结果 = 789172// 这种是什么都不会输出的 {} 会优先当成一个代码块执行const fn = () => {name:"孙悟空"}console.log(fn())// 改写方式 const fn1 = () =>( {name:"孙悟空"});console.log(fn1());//{name: '孙悟空'}</script>
九、作用域
作用域(scope)
作用域指的是一个变量的可见区域
作用域有两种:
全局作用域
- 全局作用域在网页运行时创建,在网页关闭时消耗
- 所有直接编写到script标签中的代码都位于全局作用域中
- 全局作用域中的变量是全局变量,可以在任意位置访问
局部作用域
- 块作用域
- 块作用域是一种局部作用域
- 块作用域在代码块执行时创建,代码块执行完毕它就销毁
- 在块作用域中声明的变量是局部变量,只能在块内部访问,外部无法访问
使用方式
<script>let a = '变量a';// 为全局作用域//代码块1{let b = '变量b' {console.log('a=',a);// a= 变量aconsole.log('b=',b);// a= 变量a}}//代码块 2 {console.log('a=',a);// a= 变量aconsole.log('b=',b);// 报错 09.作用域.html:80 Uncaught ReferenceError: b is not}</script>
十、函数作用域
函数作用域
- 函数作用域也是一种局部作用域
作用域在函数调用时产生,调用结束后销毁
- 函数每次调用都会产生一个全新的函数作用域
数中定义的变量是局部变量,只能在函数内部访问,外部无法访问
使用方式
<script>function fn() {let a = 'fn中的变量a';console.log(a)}fn();console.log(a);// 会报错 ReferenceError: a is not</script>
十一、作用域链
作用域链
- 当我们使用一个变量时,
JS解释器会优先在当前作用域中寻找变量,
- 如果找到了则直接使用
- 如果没找到,则去上一层作用域中寻找,找到了则使用
- 如果没找到,则继续去上一层寻找,以此类推
- 如果一直到全局作用域都没找到,则报错 xxx is not defined
使用方式
<script>let a = 10;{let a = '第一个代码块中的a';{let a = '第二个代码块中的a';console.log(a)}console.log(a);// 第一个代码块中的a}//方式2 let b = 33;// 全局function fn() {let b = 44;function f1() {let b = 55;console.log(b);}f1();}fn();// 55</script>