javaScript中的函数
1、Java中的伪变量foo、bar、baz
Section titled “1、Java中的伪变量foo、bar、baz”在学习编程的过程中,你可能会经常看到foo、bar、baz这些名词:
- 它们通常被用来作为函数、变量、文件的名词;
- 目前已经编程了计算机编程的术语一部分;
- 但是它们本身并没有特别的用途和意义;
- 常被称之为 “伪变量”(metasyntactic variable)
2、伪变量的由来
Section titled “2、伪变量的由来”事实上,foo、bar这些名词最早从什么时候、地方流行起来的一直是由争论的;
- 一种说法是通过Digital(迪吉多,数字设备公司,成立于1957年的美国电脑公司)的手册说明流行起来的;
- 一种说法是说源自于电子学中的反转foo信号;
- 也有一种说法是foo因为出现在了一个漫画中,漫画中foo代表“好运”,与中文的福读音类似;
- 总之,foo、bar、baz已经是编程领域非常常用的名词。
3、js中函数介绍
Section titled “3、js中函数介绍”函数就是一段具有特殊功能代码的封装,用来提高编写的效率以及代码的重用;
默认情况下JavaScript引擎或者浏览器会给我们提供一些已经实现好的函数;
例:console.log() alert() prompt()
-
函数代码块默认不会执行的,调用时才会执行
-
注意:函数调用的时候要分清什么时候在变量后面加括号
Section titled “注意:函数调用的时候要分清什么时候在变量后面加括号”- 将函数赋值给变量或者赋值给形参的时候不要添加(),没有return 默认返回值是 undefined。
- 只有函数调用执行的时候添加()
4、函数调用及返回值
Section titled “4、函数调用及返回值”函数的默认调用
Section titled “函数的默认调用”函数的默认调用就是,自行调用,无论在那段代码里面自行调用this就是windows
返回值注意事项(3点)
Section titled “返回值注意事项(3点)”函数的返回值默认 undefined;
- 如果函数中没有使用 return语句 ,那么函数有默认的返回值:undefined;
- 如果函数使用 return语句,但是return后面没有任何值,那么函数的返回值也是 undefined;
- 如果在函数执行到 return关键字时, 函数会 立即停止执行, 退出函数
- 在 javaScript 代码当中
return不能在 for 循环中使用
- 注意:箭头函数 一行代码 的时候可以省略大括号的return
5、函数的形参、实参、arguments参数
Section titled “5、函数的形参、实参、arguments参数”函数的参数,增加函数的 通用性,针对 相同的数据处理逻辑,能够 适应更多的数据
5.1、形参
Section titled “5.1、形参”形式参数:定义 函数时,小括号中的参数,是用来接收参数用的,在函数内部 作为变量使用
函数在定义的时候用来接受参数的
// name/age/height称之为函数的参数(形参, 形式参数, parmaters) function printInfo(name, age, height) { console.log(`my name is ${name}`) console.log(`age is ${age}`) console.log(`height is ${height}`) }5.2、实参
Section titled “5.2、实参”实际参数:调用 函数时,小括号中的参数,是用来把数据传递到 函数内部 用的
函数调用的时候传入的实际参数
// why/18/1.88称之为函数的参数(实参, 实际参数, arguments) printInfo("why", 18, 1.88) printInfo("kobe", 30, 1.98)5.3、arrguments类数组
Section titled “5.3、arrguments类数组”arguments 是一个类数组对象,不是数组对象,存在当前函数执行上下文当中,执行代码之前会初始化这个对象用来保存实参
-
arguments变量的类型是一个object类型( array-like ),不是一个数组,但是和数组的用法看起来很相似;
//node中展示的类型 看着比较像数组实际是个类数组[Arguments] { '0': 123, '1': 123, '2': 124 } -
该对象中存放着所有的调用者传入的参数,从0位置开始,依次存放;
-
在函数的代码块中直接获取,无论有没有设置参数
function baz(){//这样也能获取到console.log(arguments)//将一个可迭代的对象转化成数组var arr = Array.form(arruments)}baz(1123,31231,3123)
注意:“类数组” 表示arguments具有 length 从零开始索引的属性和属性,但它没有像Array这样的内置方法。
- 可以使用
Array.form(arguments)生成数组.来使用数组中的方法
5.4、javaScript中的参数传递
Section titled “5.4、javaScript中的参数传递”参数传递就是将实参的 值传递 给形参
- 值传递:原始类型的参数传递就是值传递,会将栈空间的值复制一份 最后赋值给形参
- 引用传递:对象类型的参数传递就是引用传递,会将栈空间的16进制0x…的地址值复制一份,赋值给形参。
5.5、es6中扩展运算符…args
Section titled “5.5、es6中扩展运算符…args” function baz(...args){//这样也能获取到 console.log(arguments) } baz(1123,31231,3123)Rest parameters
Section titled “Rest parameters”箭头函数中使用 …rest 不能像arguments那样单独的打印rest 就是个概念
- 不会计算在函数对象的
length属性当中 - 只能放到,参数的最后面
5.6、函数形参和实参不匹配的情况
Section titled “5.6、函数形参和实参不匹配的情况”- 实参多于形参的时候,有几个形参就取几个,不会报错 arguments会存在所有实参
- 实参少于形参的时候,同样不会报错,有几个便用几个
6、函数的递归
Section titled “6、函数的递归”递归:一种函数调用自身的操作,会占用较大资源,性能是比较低,会创建多个执行上下文栈(占用过多的栈内存),默认情况下会产生无限调用的情况,谨慎使用添加判断
7、局部变量和外部变量
Section titled “7、局部变量和外部变量”-
内部的变量: 定义在函数内部的变量,被称之为局部变量(Local Variables)。
-
外部的变量: 定义在函数外部的变量,被称之为外部变量(Outer Variables)。
-
全局变量: 函数之外声明的变量(在script中声明的),称之为全局变量
-
注意:通过var声明的全局变量会在window对象上添加一个属性 很重要的一点全局变量不会被垃圾回收机制回收
这个特性在不使用框架的情况下可以定义全局变量,因为变量的添加在window对象上的,windows又是全局变量。
不适用var 声明的全局变量是不规范的。
-
7.1、函数中变量访问的顺序链式查找(作用域链)
Section titled “7.1、函数中变量访问的顺序链式查找(作用域链)”优先访问自己函数(当前作用域)中的变量,没有找到时,在外部中访问,就是一层一层的找就近原则,最后会找到window 找不到返回undefined
7.2、作用域(Scope)
Section titled “7.2、作用域(Scope)”表示一些标识符的、语句、表达式的有效范围, JavaScript(ES5之前中没有块级作用域的概念 例:if ),但是函数可以有自己的作用域。
- 函数的作用域表示在函数内部定义的变量,只有在函数内部可以被访问到;
function foo(){ console.log(message) //这种情况不会提示Uncaught ReferenceError: message is not defined //而是打印undefined,因为变量会提升 var message=null;}8、创建函数的两种方式
Section titled “8、创建函数的两种方式”无论函数是如何创建的,函数都是一个值(这个值的类型是一个对象)。
8.1、JavaScript创建函数的时机(预解析)
Section titled “8.1、JavaScript创建函数的时机(预解析)”当 JavaScript 准备 运行脚本时,首先会在脚本中寻找全局函数声明,并创建这些函数
- 函数表达式是在代码执行时被创建的,并且仅从那一刻起才可调用。
- 而函数声明则是 在JavaScript 准备运行脚本时就被创建了,在函数中也是一样,所以可以直接调用。
- 这样的话优先使用函数声明的方式
8.2、第一种函数表达式(Function Expressions)
Section titled “8.2、第一种函数表达式(Function Expressions)”函数表达式:在一个表达式中或另一个语法结构中创建的函数。
- 函数表达式允许省略函数名。添加也不会生效,就是不报错而已 但个人觉得不规范
var bar = function(){ console.log("这里是bar函数")}8.3、第二种函数声明
Section titled “8.3、第二种函数声明”函数声明:在主代码流中使用function关键字声明单独语句的函数。
function foo() { console.log(message) var message=null;}javaScript运行机制-变量和函数的预解析
Section titled “javaScript运行机制-变量和函数的预解析”JavaScript代码是由浏览器中的JavaScript解析器来执行的。JavaScript引擎(解析器)在运行JavaScript代码的 时候分为两步: 预解析和代码执行。
- 预解析:js引擎会把js里面 所有的 var 还有 function提升到当前作用域的最前面
- 代码执行:按照代码书写的顺序从上往下执行
变量预解析(变量提升)
Section titled “变量预解析(变量提升)”变量提升就是将所有的变量声明提升到当前作用域的最前面 只是提升变量没有赋值的操作
例如:
console.log(num)var num = 100;// 解析之后 变量的声明提升到当前作用域的最前面var num;//这里打印的是undefiinedconsole.log(num)num=100函数预解析(函数提升)
Section titled “函数预解析(函数提升)”函数提升就是把所有的函数声明提升到当前作用域的最前面 不调用函数
-
所以函数声明会预编译
-
函数的表达式是变量赋值的形式,所以只能是变量提升
foo()var foo = function() {}//解析之后是var foo;foo() //所以这里报foo不是一个函数foo = function() {}
9、JavaScript头等函数
Section titled “9、JavaScript头等函数”头等函数(first-class function;第一级函数)是指在程序设计语言中,函数被当作头等公民 。
-
头等函数:函数可以作为别的函数的参数、函数的返回值,赋值给变量或存储在数据结构 例:Array 和{}…等数据结构中具有这些特征的函数就是头等函数;
-
有人主张也应包括支持匿名函数
var bar = function(){return () => {console.log("bar")}}//注意:这里bar要加()var bar1=bar();
函数作为作为头等公民的编程方式,称之为函数式编程
javaScript就是符合函数式编程的语言,这个也是JavaScript的一大特点;
10、回调函数
Section titled “10、回调函数”执行某些操作后执行的函数
回调函数是作为参数传递给另一个函数,并在其父函数完成后执行的函数。
接受一个或多个函数作为输入或者输出一个函数,这种函数称之为高阶函数;
//通常异步调用的时候没有等待返回值的时候使用,什么时候执行完什么时候调用函数,应该是这个意思function baz(result,fu=function(){}){ result="这里是fn" fu(result)}var result=null;baz(result,(rs)=>{console.log(rs)})//output 这里是fn11、JavaScript 中的数字分隔符(es12)
Section titled “11、JavaScript 中的数字分隔符(es12)”引入数字分隔符 ( ) 是为了通过在数字之间使用 “_” 创建视觉分隔,来使数字更具可读性。分隔符可用于十进制、二进制、十六进制或 BigInt 数字。这个特性是在ES12中引入的。
-
数字末尾不允许使用数字分隔符。因此,以下号码无效。
123_00_ -
此外,如果数字以_开头,
_JavaScript 会将其视为变量。在 JavaScript 中,变量可以以_.const a = _123; -
浏览器兼容性
所有主流浏览器都支持数字分隔符。我们可以通过访问此CanIuse链接查看准确信息
例:1000_0000_0000 可以提高代码的可读性
在java中数字分割符是Java7引入的新特性。分割数字增强可读性
js中应该也是吧
12、立即执行函数(闭包)
Section titled “12、立即执行函数(闭包)”专业名字:Immediately-Invoked Function Expression(IIFE 立即调用函数表达式)
立即执行函数的作用
Section titled “立即执行函数的作用”普通Script标签内的代码 和 和 立即执行函数都会在加载js的时候被执行
- 会创建一个独立的执行上下文环境,可以避免外界js访问或修改内部的变量,也避免了对内部变量的冲突
- 因为S5之前中没有块级作用域的概念,最早用来解决javaScript没有作用域的问题,例:for循环之后i值的问题
立即执行函数的几种写法
Section titled “立即执行函数的几种写法”立即执行函数必须是函数表达式,不能式函数声明。所以可以将函数声明成表达式的情况下都可以用()立即执行
简单来说使用表达式声明的函数都是可以立即执行的
-
立即执行函数(常用的写法)
使用分组运算符来让函数变成一个表达式,例(2+3)*8,(function() {})
var result = (function(i) {console.log("立即执行函数被调用~")})(i) -
立即执行函数的其他写法
使用 !+ - 可以让函数变成表达式的都可以
(function() {}) ()//常用的!function(){}()+function foo() {}()
注意事项 立即执行函数要使用分号结尾
Section titled “注意事项 立即执行函数要使用分号结尾”**当一行代码后面紧跟着{} ,() 或者[] 的时候,js引擎不会将换行符转换成 ;的,会被认为于后面的代码是一个整体 **
例如
- if会将后面的()和{}当作整体
- 获取对象值的时候会将[]当作整体
结论:当后面如果要使用立即执行函数的时候前一行记得添加
;, 表示当前行代码结束,最好后面也添加上
13、代码的书写规范
Section titled “13、代码的书写规范”- foo和()之间不需要有空格
- 多参数
,后面加上一个空格 - () 和 { 之间有一个空格
- { 和其他函数定义在同一行中
- for 和 ()之间和
;后要有空格 - 运算符之间要有一个空格
- if else 前后的 () {} 间隔一个空格
- es6 字符串字面量 ${} 前后要留一个空格
- 逻辑块之间 留取一个空行的间隔
14、Chrome的debug调试技巧
Section titled “14、Chrome的debug调试技巧”Snipaste_2022-05-12_22-29-28.png
- Chrome开发者工具Console区域: 可以查看代码中使用console.log() 输出的信息
- 给代码添加断点(breakpoint): 代码运行时遇到断点便会停止执行
- VSCode中,点击对应的代码行号左侧的红点即可添加断点,或者在代码上方加上 debugger
- Chrome中Source区域:找到要调试的文件,在代码左侧的行号处点击即可添加断点
- Watch区域: 输入对应的变量,可以观察代码运行过程中变量的值的变化情况
- Breakpoints区域: 可以查看js代码中所有非代码
debugger添加的断点 - Scope区域: 查看代码生成的作用域
- 上方工具栏按钮作用(从左到又):
- 控制调试程序的暂停和恢复
- 跳过下一个函数调用,执行下一行代码
- 进入下一个函数调用,可查看函数内部执行顺序
- 跳出当前函数
- 进入下一个函数调用,不会进入setTimeout内部的函数
重点:函数的调用还有返回值
E:\coder why前端系统课\练习作业\4.node_webpack工程化\03_包管理工具使用\06_why_utils\src
