目录
3.3.2 声明式函数 赋值式函数 定时器 延时器 forEach ....
一、立即执行函数
1.1 定义
普通函数分为定义封装和调用执行两个步骤,封装函数时只是在定义一个函数并没有执行,立即执行函数,一般都是匿名函数,在封装定义函数的同事就调用执行函数。
1.2 语法形式
1.2.1 不带参数形式
(匿名函数)();
!匿名函数();
~匿名函数();
1.2.2 带有参数形式
(function(形参){})(实参);
1.3 注意
立即执行函数后必须要写分号。
代码演示:
//正常情况
// 只是封装定义函数 没有调用执行函数
function fun( string ){
console.log( string );
}
// 调用执行函数
fun( '北京' );
// 立即执行函数
// 不带参数形式
// (匿名函数)() 在 封装定义匿名函数的同时 调用执行匿名函数
(function(){ console.log(222) })();
!function(){ console.log(333) }();
~function(){ console.log(444) }();
// 带有参数的立即执行函数
(function( string ){ console.log( string ) })( '上海' );
运行结果:
二、箭头函数
2.1 定义
ES6新增的一种匿名函数的语法形式,箭头函数是一种非常重要的匿名函数的语法形式,本质作用是为了ES6新增的class构造函数定义的,为了配合面向对象编程定义的。
function (){} 匿名函数
() = > {} 箭头函数
2.2 关键作用
箭头函数和普通函数程序的this指向不同
2.3 语法形式
() = > {} 箭头函数
如果只有一个形参可以不写()
形参 => {}
如果只有一行代码可以不写{}
形参 => 程序代码 ;
代码展示:
<div>我是div标签</div>
<script>
// 获取标签对象
const oDiv = document.querySelector('div')
// 普通的匿名函数
oDiv.addEventListener( 'click' , function(){ console.log(111) });
// 箭头函数语法
oDiv.addEventListener( 'click' , () => { console.log(222) });
// 箭头函数语法
// 如果只有一个形参 可以不写 ()
oDiv.addEventListener( 'click' , e => { console.log(333) });
// 箭头函数语法
// 如果只有一行代码 可以不写 {}
oDiv.addEventListener( 'click' , e => console.log(444) );
</script>
运行结果:
三、this指向
3.1 定义
this是面向对象编程中非常重要的关键词,是函数中特有的关键词,调用执行函数程序时,JavaScript程序自动设定this关键词的指向。
3.2 this指向的理解
this 是JavaScript中的函数关键词,本质是一个对象,对象中存储的内存地址,这个内存地址指向的是堆中的一个独立的存储空间,,所谓的this指向,就是this这个对象存储的内存地址指向的存储空间,也就是this中存储的数据数值。
在不同的函数程序中this指向也是不同的。也就是不同的函数中 this 存储的内存地址 和指向的存储空间是不同的。
3.3 不同函数的具体的this指向
3.3.1 普通函数
this指向是window顶级对象
代码展示:
// this指向是 window
// this指向是 window 实际项目中 没有什么作用
// 声明式函数
function fun1(){console.log( this );}
fun1();
// 赋值式函数
const fun2 = function(){console.log(this)};
fun2();
运行结果:
3.3.2 声明式函数 赋值式函数 定时器 延时器 forEach ....
事件处理函数中的this指向
this 指向的是事件源
代码展示:
<div>
我是div
<p>我是p标签</p>
<span>我是span标签</span>
<h1>我是h1标签</h1>
</div>
<script>
const oDiv = document.querySelector('div');
oDiv.addEventListener( 'click' , function(e){
// 事件对象 触发事件的标签对象
console.log( e.target );
// this指向 始终是事件源
// 也就是绑定事件的标签对象
console.log( this );
// this就是事件源标签对象可以直接进行DOM操作
this.style.color = 'blue';
this.style.background = 'pink';
})
</script>
运行结果:
存储在 数组/对象 中的函数
this指向是 数组/对象
代码展示:
// 存储在数组中的函数
const arr = [1,2,3,function(){console.log(this)} ] ;
// 调用执行 数组中的函数
// 函数的this 指向的就是数组本身
arr[3]() ;
// 存储在对象中的函数
const abc = {
name:'张三',
age:18,
sex:'男',
addr:'北京',
fun:function(){
console.log(this) ;
// this就是对象本身 可以通过 this.属性 调用属性值
console.log(this.name) ;
console.log(this.age) ;
console.log(this.sex) ;
console.log(this.addr) ;
}
};
// 调用执行对象中的函数
abc.fun() ;
运行结果:
3.2 箭头函数的this指向
- 普通函数的this指向不是固定的是可以改变的。
- 箭头函数的this指向是固定的,不能改变的。
- 箭头函数的this指向是父级程序的this指向,如果没有父级程序或者父级程序没有this那么箭头函数的this执向是window。
代码展示:
<div>我是div标签</div>
<script>
// 没有父级程序 箭头函数this 指向是 window
const fun1 = () => {console.log(this)};
fun1();
const oDiv = document.querySelector('div');
// 普通函数 事件处理函数中的this 指向 事件源标签对象
oDiv.addEventListener('click' , function(){
console.log(this);
})
// 箭头函数 事件处理函数中的this指向 是 父级程序的this指向
// 没有父级程序 this指向 是 window
oDiv.addEventListener('click' , () => {
console.log(this);
})
</script>
运行结果:
3.3 改变this指向
3.3.1 定义
通过JavaScript提供的函数方法,改变普通的this指向,箭头函数的this指向只能是父级程序this指向。
3.3.2 语法
call () 语法
函数.call(参数一,其他参数);
参数一 设定的函数新的this指向
其他参数 原始函数需要的参数
apply() 语法
函数.apply(参数一, [其他参数] );
参数一 设定的函数新的this指向
其他参数 原始函数需要的参数
bind () 语法
生成 一个新的函数 同时改变函数的this指向
const 变量 = 函数.bind( 参数1 , 其他参数 );
参数1 设定的生成的新函数的this指向
注意:这里的其他参数设置了就是绑定的意思后续再赋值形参时,不会生效。
代码展示:
const obj1 = {name:'张三' , age:18 , sex:'男'};
function fun1(){
console.log(this);
console.log(111);
}
// 通过bind() 生成一个新的函数 同时 改变this指向
// 生成一个新的函数fun2 所有的函数程序内容 都和 函数fun1 相同
// 只是this指向 被设定为 obj1
const fun2 = fun1.bind( obj1 );
fun2();
function fun3( a , b, c ){
console.log( a , b , c );
console.log(this);
}
// 生成新的函数fun4 程序代码和fun3相同 只是修改了this指向
const fun4 = fun3.bind( obj1 );
// 调用时需要输入 实参数据
fun4( 'x' , 'y' , 'z' ) ;
// 生成新的函数fun5 程序代码和fun3相同 只是修改了this指向
// 并且 给 形参 绑定了 实参 数据
const fun5 = fun3.bind( obj1 , 'aaa' , 'bbb' , 'ccc');
fun5( 'ddd' , 'eee' , 'fff') ;
运行结果:
四、合并展开运算符
4.1 展开运算符(定义在实参位置)
function fun(){}
fun(...数组);
将 数组单元的数据 展开 一一对应的的赋值给函数的形参
// 展开运算符
function fun(a,b,c,d,e,f,g){
console.log( a,b,c,d,e,f,g );
}
const arr = [100,200,300,400,500,600,700];
// 不用展开运算符调用数组内容
// fun( arr[0] , arr[1] , arr[2] , arr[3] , arr[4] , arr[5] , arr[6] );
// 将 数组arr 中 每一个数据单元的数据 展开 一一对应的赋值给函数的实参
fun( ...arr );
运行结果:
4.2 合并运算符(定义在实参位置)
function fun( a,b,...arr ){}
以 数组的形式 存储 对应的实参
4.3 arguments
函数 特有的关键词
以 伪数组的形式 存储 所有的实参
伪数组 不能 forEach 循环遍历
代码展示:
// 合并运算符
// 正常情况下 一个形参只会存储一个实参
function fun2( arr ){
console.log( arr );
}
fun2( 100 , 200 , 300 , 400 );
// 通过 合并运算符 定义 形参
// 存储对应的实参
// 第一个实参赋值给第一个形参 a
// 第二个实参赋值给第二个形参 b
// 之后所有的实参 以数组的形式存储在 arr中
function fun3( a , b, ...arr ){
console.log( a );
console.log( b );
console.log( arr );
// arguments关键词 以 伪数组形式 存储 所有实参
// 伪数组 不能 forEach 循环遍历
console.log( arguments );
}
fun3( 100 , 200 , 300 , 400 , 500 , 600 ,700);
运行结果:
五、解构赋值
5.1 定义
一种将数组或者对象一一对应赋值给变量的简易语法形式
5.2 数组的解构
let [变量1,变量2,变量3...] = 数组 ;
将数组中的数据解构之后一一对应的赋值给变量,一个人数组单元对应一个变量,一个多维数组对应一个人[]。
// 数组的解构赋值
const arr = [100,200,300,400,500,[600,700,800,[900,100]]];
// 普通的[]语法 获取数据赋值
// let a = arr[0];
// let b = arr[1];
// let c = arr[2];
// let d = arr[3];
// let e = arr[4];
// 结构赋值
let [a,b,c,d,e,[f,g,h,[i,j]]] = arr ;
console.log( a , b , c , d , e , f , g , h , i , j);
运行结果:
5.3 对象的解构
let { 键名1, 键名2 , 键名3.... } = 对象;
以键2名作为变量从对象中获取数据,存储在以键名作为变量名称的变量中。
// 对象的解构赋值
const obj = {name:'张三' , age:18 , sex:'男' , addr:'北京' , phone:{ id1:123 ,id2:456 , id3:789 } , email:['1@qq.com','2@qq.com','3@qq.com'] };
// 使用 键名 作为 变量
// 通过 键名 从 对象中获取数据
// 存储在键名作为名称的变量中
// name 是 变量 也是 键名
// 使用 name键名 从 对象obj中 获取数据 张三
// 存储 到 name变量中
// let {name , age , sex , addr} = obj ;
// console.log( name , age , sex , addr );
// 使用 name作为键名 从 对象obj 中获取数据
// 存储 到变量a 中
let {name:a , age:b , sex:c , addr:d , phone:{ id1:p1 , id2:p2 , id3:p3 } , email:[e1,e2,e3] } = obj ;
console.log( a , b , c , p1 , p2 , p3 , e1 , e2 , e3);
运行结果:
六、map数据类型
6.1 定义
map数据类型,是ES6新增的数据类型,适合复杂项目中的一种数据类型,类似于对象结构。
6.2 创建
const 变量 = new Map( [ [键名,键值] , [键名,键值] , [键名,键值] ....] ) ;
6.3 函数方法
6.3.1 设定
map对象.set(键名 , 键值)
6.3.2 获取
map对象.get(键名)
6.3.3 删除
map对象.delete(键名)
6.3.4 清空
map对象.clear()
6.3.5 循环遍历
map对象.forEach(function(参数1,参数2,参数3){})
参数1 map中的键值
参数2 map中的键名
参数3 原始map
代码展示:
// 创建map数据类型
const map = new Map([ ['name','张三'] , ['age',18] , ['sex','男'] ]);
// 新增
map.set( 'addr' , '北京' );
map.set( 'phone' , 123 );
// // 获取
console.log( map.get('addr') );
// // 删除
map.delete( 'name' );
// // 清空
// map.clear();
// 循环遍历
map.forEach(function(a,b,c){
console.log( a , b , c );
})
console.log( map );
七、set数据类型
7.1 定义
set数据类型,ES6 新增的数据类型,类似于 数组的数据类型,set数据类型不会存储重复的数据。
7.2 创建set数据类型
const set = new Set( 数组 ) ;
7.3 函数方法
7.3.1 新增
set对象.add()
7.3.1 删除
set对象.delete()
7.3.1 清空
set对象.clear()
7.3.1 判断有没有
set对象.has()
7.3.1 循环遍历
set对象.forEach(function(参数1,参数2,参数3){})
参数1 set类型的数据
参数2 set类型的数据
参数3 原始set
// 创建 set数据类型
const set = new Set( [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5] ) ;
// 新增
set.add( 100 );
set.add( 200 );
set.add( 300 );
set.add( 400 );
// // 删除
// set.delete(200);
// // 清空
// set.clear();
// 判断有没有
console.log( set.has(5) );
// 循环遍历
set.forEach( function(a,b,c){
console.log(a,b,c);
} )
console.log( set );
运行结果: