公式
// 函数定义 =》标准的代码块=》有函数作用域
function func(形参1,形参2,形参3,...) { // 函数名
//函数体 里面执行函数语句
return null // 返回值
}
func(1,2) // 函数调用 实参
什么是函数
将重复代码进行封装,类似特定产品的机器、工厂。
函数是一块具有作用域的功能体。
作用域:变量和函数的可访问范围
变量分为两种
全局作用域:在函数外,使用var关键字声明的变量,可以在任意位置可以访问的
函数作用域(局部作用域):在函数内,使用var关键字声明的变量,只能在函数内部访问到
函数的作用域
函数的可访问范围,和变量的作用域一样,也分为全局作用函数,局部作用函数;全局作用域在任意函数均可以调用,局部作用域只能在函数内部使用。
注意:
变量
(1)函数内没有使用var关键字声明的变量,自动是全局变量 如 e=9;
(2)函数的参数本质是局部变量,不能被外部访问。
(3)JS没有块级作用域。即{}不一定是作用域,只有函数作用域和全局作用域
js运行机制
变量声明提升
JS程序在执行前,会将var声明的变量提升到所在作用域的最前面,但赋值还是在原来的位置。
2.函数声明提升
JS程序在执行前,会将函数声明提升到所在作用域的最前面,但执行还是在原来的位置。
函数定义
方式一:function关键字定义
function func() {
//函数体 =》代码块
}
方式二:(函数表达式定义)函数字面量定义
const func = function() {
//函数体 =》代码块
}
方式三:Function构造函数创建 (最后一个参数为函数体 字符串)
let func = new Function ([arg1, arg2, ...argN], functionBody);
let sum = new Function('a', 'b', 'return a + b');
alert( sum(1, 2) ); // 3
扩展
变量提升:js引擎解析js代码时会将当前作用域内的变量和常量的声明提前,形成作用域对象,然后再依次赋值,同时当前作用域对象会指向上一级的作用域对象,形成作用域链。
函数提升: 其实本质是变量的提升:区别在于最开始提升的时候是一个函数,还是一个未赋值的变量
函数分类
**普通函数:**介绍普通函数的特性:同名覆盖、arguments对象、默认返回值等。
**匿名函数:**介绍匿名函数的特性:变量匿名函数、无名称匿名函数。
**闭包函数:**介绍闭包函数的特性。
arguments对象
-
存在于函数内部 是个类数组 可以获取到所有实参传递的参数(即使形参只定义了一个,只有实参传了多个都可以获取到)
-
存在于函数(非匿名函数)调用时,和this相同都是 在函数调用的时候传递进两个隐式参数
-
arguments 运行时可以修改实参
引用
arguments 对象实际上是所在函数的一个内置类数组对象
每个函数都有一个arguments属性,表示函数的实参集合,这里的实参是重点,就是执行函数时实际传入的参数的集合。arguments不是数组而是一个对象,但它和数组很相似,所以通常称为类数组对象,以后看到类数组其实就表示arguments。arguments对象不能显式的创建,它只有在函数开始时才可用。
arguments还有属性callee,length和迭代器Symbol。
arguments同样具有length属性,arguments.length 为函数实参个数,可以用arguments[length]显示调用参数
arguments对象可以检测参数个数,模拟函数重载
理解点
第一点:arguments对象:可以在函数内访问所有的参数,实参
第二点:在正常的模式下,arguments对象可以在运行的时候进行修改
第三点:在严格的模式下,arguments对象在运行的时候不可以修改,修改arguments对象不会影响到实际的函数参数
第四点:通过arguments对象的length属性,可以判断实参的个数
第五点:arguments是一个对象,不是数组,转换为数组可以采用 slice 和 逐一填入新数组
第六点:arguments的callee属性可以返回对应的原函数,达到调用自身函数的效果,但是在严格模式中是不适用的
箭头函数
(形参1,形参2)=>{ // 箭头函数本质也是匿名函数
//函数体
}
- 箭头函数内this指向上下文对象 也就是箭头函数处在有效的作用域内的this 指向相同
- 箭头函数没有arguments
- 本质是匿名函数 避免函数名污染
闭包:
函数嵌套函数,形成两个或多个作用域对象,内层函数引用外层函数的变量或常量(外层函数的 作用域对象值)导致外层函数无法释放,形成闭包
-
作用:局部变量有全局变量的优点,同时不影响,不生成全局变量
-
有效解决js中没有块级作用域的特点 es6中引入了 let 和const 有效的解决了块级作用域问题
function funA(arg1,arg2) { var i = 0; function funB(step) { i = i + step; alert(i) } return funB; } var allShowA = funA(2, 3); //调用的是funA arg1=2,arg2=3 allShowA(1);//调用的是funB step=1,输出 1 allShowA(3);//调用的是funB setp=3,输出 4
立即执行函数
概念: 声明就立即执行的函数
例子:匿名函数自调用 (function(){})()
(function(){})()是匿名函数,主要利用函数内的变量作用域,避免产生全局变量,影响整体页面环境,增加代码的兼容性。
// 形式有
(function(){ /* code */ }())
// 或者
(function(){ /* code */ })()
!function(){}
~function(){}
+function(){}
-function(){}
void function(){}
函数体
break🐰 用来 终止本轮循环(包含for 和while循环),让本轮循环不再往下继续
continue💛用来跳过本轮循环的本次循环,继续往下循环
return👿 只能出现在函数里,表示结束函数,然后函数结果 注⛔️ 如果出现在for循环或者while循环里 会报错
for基础
//基本使用
let arr = ['a','b','c','d','e','f','g']
for (var i=0; i<arr.length;i++){ // i是下标(索引)
console.log(i)
console.log(arr[i])
}
// 执行顺序 for(步骤1;步骤2;步骤4) {
// 步骤3
}
for 语句是同步语句 会依次执行下去 和 break continue 配合会 控制 本轮循环 的执行次数
举例:break 💔 continue 🎛 return ♻️ 控制循环
let arr = ['a','b','c']
for 本轮循环内的break =》执行一次for循环结束
for (var i=0; i<arr.length;i++){ // i是下标(索引)
console.log(i)
break
} // 0 =》成立
for 循环内continue => 循环执行到continue 终止本次循环 开始执行下次循环
for (var i=0; i<arr.length;i++){ // i是下标(索引)
console.log(i)
break
console.log('这是continue下面文字')
} // 0 1 2 =>成立
for 使用 return 报错
数值 forEach 使用 break continue 无法控制forEach的遍历 return 也不行
如果要控制 可以使用 throw new Error('') 配置try catch 终止整个循环
for in 和for of的区别
for in: 遍历对象 =》遍历的是key
let obj={
key1:1,
key2:2
}
let arr = ['a','b','c']
for (let i in obj) {
console.log(i)
}// key1 key2 =>for in 遍历的是对象的key
for (let i in arr) {
console.log(i)
}// 0 1 2 =》 数组本质也是对象 可以遍历
for of:遍历数组=》无法遍历 不可迭代对象
可迭代对象包括: Array,Map,Set,String,TypedArray,arguments等等
let obj={
key1:1,
key2:2
}
let arr = ['a','b','c']
for (let i of obj) {
console.log(i)
}// 报错 obj is not iterable
for (let i of arr) {
console.log(i)
}// a b c => 只能遍历数组 遍历的是数组中的值
for in 💢 for of 是否可以使用break continue
let obj={
key1:1,
key2:2
}
let arr = ['a','b','c']
for (let i in obj) {
break
console.log(i)
}// undefined =>可以使用break
结论:🐰 都可以使用 continue break 来控制循环
资料:
Function
代码运行机制(是js语言本身具备的,与运行环境无关)
1)先进行预编译,将所有变量,函数声明进行编译
2)将所有var声明的变量进行所在作用域进行变量的提升
3)检查语法
4)从上到下然后在进行运行赋值,等操作
浏览器端
扩展:
浏览器不知道服务器响应内容的编码的情况下会按照当前操作系统的默认编码去解析
中午操作系统默认gbk;
浏览器默认将服务器端传来的html标签进行编译,
即:不显示html标签,只显示样式。