1.ES6的箭头函数
ES6 的箭头函数
+ ES6 语法内一种定义函数表达式的方式
=> 注意: 声明式函数不能用
=> 所有匿名函数位置都可以使用
-> var fn = function () {}
-> var obj = { f: function () {} }
-> xxx.forEach(function () {})
-> setTimeout(function () {})
-> xxx.onclick = function () {}
-> ...
+ 语法: () => {}
() 书写 形参 的位置
=> 箭头函数的标志
{} 书写函数体的位置
箭头函数的特点
1. 可以省略 () 不写
=> 当你只有一个形参的时候, 可以不写小括号
2. 可以省略 {} 不写
=> 当你的函数体只有一句话的时候, 可以省略 {}
=> 并且会把这一句话的结果当做 返回值
3. 箭头函数内没有 this
=> 箭头函数内没有自己的 this
=> 箭头函数内的 this 就是外部作用域的 this
4. 箭头函数没有 arguments
=> 箭头函数内没有 arguments 这个实参的集合
5. 箭头函数不能被改变 this 指向
=> call / apply / bind 都不能改变 箭头函数的 this 指向
6. 箭头函数不能被当做构造函数使用
=> 箭头函数不能和 new 关键字连用
例:
箭头函数的定义
var f1 = function () { console.log('函数表达式') }
var f2 = () => { console.log('箭头函数') }
特点1:
var f1 = () => { console.log('hello world') }
f1()
var f2 = a => { console.log('hello world', a) }
f2(100)
var f3 = (a, b) => { console.log('hello world', a, b) }
f3(10, 20)
特点2:
var f1 = (a, b) => { return a + b }
console.log(f1(10, 20))
var f2 = (a, b) => a + b
console.log(f2(100, 200))
特点3:
var obj = {
f1: function () { console.log(this) },
f2: () => console.log(this)
}
obj.f1()
obj.f2()
特点4:
var fn = () => console.log(arguments)
fn()
特点5:
var fn = () => console.log(this)
fn()
fn.call({ name: 'Jack' })
2.This指向
箭头函数最重要的目的是解决this指向问题
this 指向
+ 指向: 指引用地址的方向
+ 表达: this 到底是什么
+ 需要结合上下文, 决定不同位置的 this 指向的内容不一样
this 是一个关键字(熟读并背诵全文, 手抄)
+ 是一个使用在作用域内的关键字
=> 要么用在全局
-> 因为在全局使用 this 的时候
-> this 指向 window
=> 要么用在函数内
+ 函数内的 this (this只看函数调用 哪个函数里的this就看哪个函数)
=> 重点: 不管函数定义在哪, 不管函数怎么定义, 只看函数如何被调用(箭头函数除外)
=> 普通调用
-> 函数名()
-> this 指向 window
=> 对象调用
-> 对象名.函数名()
-> this 指向 对象(点前面是谁就是谁)
=> 定时器调用
-> setTimeout(函数, 数字)
-> setInterval(函数, 数字)
-> this 指向 window
=> 事件处理函数
-> 事件源.on事件类型 = 函数
-> 事件源.addEventListener(事件类型, 函数)
-> this 指向 事件源
=> 未完待续 ...
2.1 This指向补充
This指向在js中是非常丰富的 还有两三个没讲
1、全局中this指向 window
2、命名函数或者匿名函数执行时 this指向window或者undefined
3、命名函数或者匿名函数在任何其他作用域中执行,this指向window或者undefined
4、对象中方法中的this指向当前对象,对象中属性中的this指向对象外上下文环境中的this
5、事件函数中this指向侦听事件的对象,谁侦听事件this就是谁
6、箭头函数中this指向箭头函数外上下文环境中的this指向
7、正常的回调函数(除事件触发的回调函数外)this全部指向window或者undefined
8、如果回调函数使用arguments的方式调用执行,被回调函数中this指向回调它的函数中arguments对象
例:
4.对象中方法中的this指向当前对象,对象中属性中的this指向对象外上下文环境中的this
var b = -1;
var o1 = {
b: 100,
init: function () {
console.log(this);
var b = 0;
var o = {
a: this.b,
b: 2,
c: function () {
console.log(this);
}
}
o.c();
console.log(o);
}
}
o1.init();
5.普通函数中指向事件侦听的对象
document.addEventListener("click",function(e){
this.clickHandler(e);
})
6、箭头函数中this指向箭头函数外上下文环境中的this指向
var fn=()=>{
console.log(this);
}
fn();
7、正常的回调函数(除事件触发的回调函数外)this全部指向window或者undefined
function fn(f){
f();
}
function fn1(){
console.log(this);
}
fn(fn1);
8.如果回调函数使用arguments的方式调用执行,被回调函数中this指向回调它的函数中arguments对象
function fn(f){
arguments[0]()
}
function fn1(){
console.log(this);
}
fn(fn1);
3.ES6解构赋值
将整体化整为零就叫做解构
ES6 的解构赋值
+ 目的: 快速从对象或者数组中获取成员
=> 解构数组(不常用)
=> 解构对象
1.解构数组(不常用)
+ 使用 [] 对数组进行解构
+ 语法: var [ 变量1, 变量2, ... ] = 数组
+ 意义: 按照索引, 把数组内的每一个数据依次赋值给 变量
+ 多维数组解构
=> 原始数组如何书写, 解构如何书写, 数据换成变量
例:
解构数组 (数组里面的元素按位赋值给前面的变量)
var arr = [ 100, 200, 300 ]
1. 解构 ( []在左边叫解构 在右边叫数组 )
var [a, b, c] = arr
console.log(a, b, c)
2. 多维数组解构 (abcdefgi 一一对应)
var arr = [ 1, 2, [ 3, 4, [ 5, 6, [ 7, 8, [ 9 ] ] ] ] ]
var [ a, b, [ c, d, [ e, f, [ g, h, [ i ] ] ] ] ] = arr
console.log(arr)
console.log(f)
console.log(i)
3. 数组的解构 + var 可以做交换变量
var a = 5
var b = 6
console.log(a, b)
var [ b, a ] = [ a, b ]
console.log(a, b)
4. 数组里面的元素按位赋值给前面的变量
var arr=[1,2,3,4];
var [a,b,c,d]=arr;
var [a,b,c]=arr;
var [a,b,c,d,e]=arr;//e=undefined
5. 如果数组中没有最后一项,e默认值为5,如果有最后一项,则赋值这个元素
var [a,b,c,d,e=5]=arr;
arr=[1,2,3,4,10] a=1 b=2 c=3 d=4 e=10
arr=[1,2,3,4] a=1 b=2 c=3 d=4 e=5
2.解构对象
+ 解构对象使用 {}
+ 语法: var { key, key2, ... } = 对象
+ 意义: 按照你写 key 去对象内获取成员
解构对象起一个别名
+ 语法: var { key: 别名 } = 对象
解构多维对象
+ 原始对象如何书写, 解构如何书写, 删除掉值即可, 如果需要别名直接书写
例:
1.解构赋值
function fn({a,b,c:{a:a1=1,b:b1=2}={}}={a:1,b:2,c:{a:3,b:4}}){
console.log(a,b,a1,b1);//1,2,3,4
}
fn({a:1});
2.解构对象起一个别名
var obj={a:1,b:{a:2,c:{a:3}}};
同名属性解构时可以使用:起别名
var {a:a1,b:{a:a2,c:{a:a3}}}=obj;
var obj={a:1,b:{a:2,c:{}}};
var {a:a1,b:{a:a2,c:{a:a3=4}}}=obj;
console.log(a1,a2,a3)
3.赋默认值
function fn(a=1){
console.log(a);
}
fn(3); //3
fn(); //1
4.Set和Map
Array 迭代器
连续按位存储的一组数据,紧密结构,删除,插入都会造成数组的结构发生改变,
因此效率较低,但是数组因为紧密性可以获取前后关系元素,可以排序,数组查找需要从头开始遍历,速度比对象慢。
数组中的元素是可以重复,数组只能按照下标存储
Object 不是迭代器
对象是按照key存储的值,key对应一个唯一的value,key不能重复,对象是一种松散结构
因此没有前后关系,也不能排序,没有顺序,松散结构添加删除速度非常快,查找元素的速度
也是非常快,对象中key不能重复,但是value可以相同,对象必须使用字符串或者symbol
作为key存储。对象没有长度
Set 类似于数组,集合 Set是松散结构,没有key只存储值,没有下标,不能重复,
每个元素唯一,有长度,set也不适用于排序,迭代器
WeakSet 弱类型Set
Map 类似于对象,HashMap,也是key-value键值对,用key来存储value,有长度
key可以是任何类型 map也不适用于排序,迭代器
WeakMap 弱类型Map
4.1 有关set:
var s=new Set([1,2,3,4,2]);
var o={a:1,b:2,c:3,d:4};
var s=new Set(Object.values(o));
console.log(s);
iterable 所有的迭代器都是可以放入
var s=new Set()
s.add(1);
s.add(2);
s.clear();
s.delete(3);
var bool=s.has(2);
console.log(bool)
console.log( s.size);
遍历1
s.forEach((value)=>{
console.log(value)
})
遍历2
for(var value of s){
console.log(value)
}
4.2 有关map:
1.entries()
2.fromEntries();
var m=new Map();
console.dir(Object);
[["a",1],["b",2]]
var o=Object.entries();
var o=Object.entries({a:1,b:2});
console.log(o)
for(var [key,value] of Object.entries({a:1,b:2})){
console.log(key,value)
}
Object.fromEntries([[key,value],[key,value]]);
var o=Object.fromEntries([["a",1],["b",2]]);
console.log(o)
var o={a:1,b:2,c:3};
var m=new Map(Object.entries(o));
console.log(m)
var m=new Map();
m.set("a",1);
m.set("b",2);
m.set("c",3);
m.clear();
m.delete("b");
var value=m.get("a");
var bool=m.has("c");
console.log(bool)
console.log(value);
console.log(m);
console.log(m.keys());
console.log(m.values());
console.log(m.size);
m.forEach((value,key)=>{
console.log(key,value)
})
for(var [key,value] of m){
console.log(key,value)
}
for(var key of m.keys()){
console.log(key)
}
for(var value of m.values()){
console.log(value)
}
for(var [key,value] of m.entries()){
console.log(key,value)
}
console.log(m.entries())
5.认识面向对象
认识面向对象
+ 面向对象是一个开发思想
+ 面向对象: 对面向过程的高度封装
+ 核心: 高内聚, 低耦合
例子: 吃面条
+ 面向过程
=> 和面: 多少面粉多少水
=> 切面: 多宽多窄
=> 煮面: 多长时间
=> 拌面: 多少酱, 多少面
=> 吃面: 用哪吃
+ 面向对象
=> 找到一个面馆
=> 点一碗面, 点完以后就等着
=> 吃面
+ 换一个思路
=> 当我想吃面条的时候
=> 我要找到一个面馆, 如果有面馆直接用就好
=> 我自己开一个面馆(自己找厨师/...)
=> 点一碗面, 等着面端上来
=> 吃面
例子: 实现轮播图
+ 面向过程
=> 获取元素(banner/imgBox/pointBox)
=> 准备变量(index/flag/timer)
=> 调用方法
-> copyEle()
-> setPoint()
-> autoPlay()
+ 面向对象
=> 我们自己把所有的过程封装起来(Swiper)
=> 我们自己直接调用使用
例子: 实现轮播图
+ 面向过程实现第一个
=> 获取元素(banner/imgBox/pointBox)
=> 准备变量(index/flag/timer)
=> 调用方法
-> copyEle()
-> setPoint()
-> autoPlay()
+ 面向过程实现第二个
=> 获取元素(banner2/imgBox2/pointBox2)
=> 准备变量(index2/flag2/timer2)
=> 调用方法
-> copyEle2()
-> setPoint2()
-> autoPlay2()
+ 面向对象实现第一个
=> banner1 = {
banner: 第一个轮播图的整体范围
imgBox: 自己的banner内查找承载图片的盒子
pointBox: 自己的banner内查找承载焦点的盒子
index: 表示索引
timer: 定时器返回值
flag: 开关
copyEle: 函数(调用的是自己的 banner/ 自己的 imgBox/ 自己的 pointBox)
setPoint: 函数
autoPlay: 函数(操作自己的 timer/ 自己的 flag/ 自己的 index)
}
+ 面向对象实现第二个
=> banner2 = {
banner: 第二个轮播图的整体范围
imgBox: 自己的banner内查找承载图片的盒子
pointBox: 自己的banner内查找承载焦点的盒子
index: 表示索引
timer: 定时器返回值
flag: 开关
copyEle: 函数(调用的是自己的 banner/ 自己的 imgBox/ 自己的 pointBox)
setPoint: 函数
autoPlay: 函数(操作自己的 timer/ 自己的 flag/ 自己的 index)
}
总结面向对象学习任务
=> 找到一个能 批量创建对象 的 "机器"(自定义构造函数)
=> "机器" 要求
-> 批量创建对象
-> 创建的对象要有属性(非函数对象成员)有方法(函数对象成员)
-> 创建出来的对象要合理
=> 使用 "机器" 创建对象