==和===的区别:
- ==: 在类型不相同的情况, 会对运算元进行隐式的转换
* 大部分情况下, 都是转成数字类型 toNumber()
* 对象类型相对比较特殊, 一般返回false
* 262.ecma-international.org/5.1/#sec-11…
- ===: 先比较类型, 类型不一致, 直接返回false
* 严格相等
函数:函数其实就是某段代码的封装,这段代码帮助我们完成某一个功能
二. 函数的基本使用
声明函数 -封装独立的功能
调用函数 -- 享受 封装 的成果
2.1. 函数的定义:
- 函数的声明
function 函数名(){
函数封装的代码
}
- 函数的调用
// 调用一个函数
sayHello()
2.2. 函数的参数
形参(参数 parameter):定义函数时,小括号中的参数,是用来接收参数用的,在函数内部作为变量使用
实参(参数 argument):调用 函数时,小括号中的参数,是用来把数据传递到函数内部用的
2.3. 函数的返回值
- 返回值的注意事项
//注意事项一: 所有的函数, 如果没有写返回值, 那么默认返回undefined
注意事项二: 我们也可以明确的写上return, 写上return关键字, 但是后面什么内容都没有的时候, 也是返回undefined
注意事项三: 如果在函数执行到return关键字时, 函数会立即停止执行, 退出函数
2.4. 函数的练习
// 10_0000_0000就是1000000000语法糖
// 语法糖的概念: 一种简写或者特殊的写法, 这种写法相对于原有的写法更加的方便或者阅读性更强
// 相比于原来的写法, 有一点点的甜头, 称之为语法糖
二. arguments参数的使用
-
默认情况下,函数中有一个arguments变量
-
变量中存储着所有传入的参数
* 对象类型;
* 通过索引获取某一个变量;
三. 递归的使用
3.1. 函数调用函数
3.2. 递归的思想
-
递归必须有结束条件
-
案例: pow
* for循环
* 递归实现
3.3. 斐波那契
-
介绍斐波那契数列
-
递归实现
-
for循环
四. 变量作用域
4.1. 什么叫做作用域
-
ES5之前是没有块级作用域(var定义变量)
-
函数的作用域
4.2. 全局/局部/外部变量
-
定义在函数内部的变量,被称之为局部变量 (Local Variables)
-
定义在函数外部的变量,被称之为外部变量(Outer Variables)
-
函数之外声明的变量(在script中声明的),称之为全局变量
4.3. 变量的访问顺序
优先访问自己函数中的变量,没有找到时,在外部中访问
函数声明vs函数表达式
五. 函数式编程中概念
概念一:函数作为一等公民
-
函数可以赋值给变量
-
函数也可以传递给另外一个函数
-
函数也可以作为另外一个函数的返回值
-
函数也可以存储在别的数据结构中
概念二:函数式编程
-
函数可以作为头等公民的编程语言,叫做函数式编程的语言;
-
JavaScript就是一种函数式编程语言;
后面三个概念在后续的学习中,我会经常提到和使用:
概念三:函数的回调
-
将一个作为另外一个函数的参数传入到另外一个函数中;
-
在另外一个函数中,对于传入的函数进行调用的过程,就叫做函数的回调
概念四:匿名函数
- 传入一个函数时,如果没有给函数名,也没有定义对应的变量的函数,就叫做匿名函数
概念五:高阶函数
-
foo可以接受另外一个函数参数,那么foo就称之为是一个高阶函数;
-
如果一个函数有返回另外一个函数,那么这个函数也叫做高阶函数;
foo(function() {
})
`
一. 立即执行函数
1.1. 立即执行函数的理解
表达的含义是一个函数定义完后被立即执行
1.2. 立即执行函数的应用
- 防止全局变量的命名冲突
- 在btns的点击中, 创建一个作用域保存i的值
1.3. 立即执行函数的其他写法(了解)
二. 代码规范
三. debug调试技巧(总结)
四. 对象的基本使用
4.1. 认识对象类型
对象类型涉及到JavaScript的各个方面,所以掌握对象类型非常重要;
对象类型是一种存储键值对(key-value)的更复杂的数据类型;
4.2. 对象的创建方式
- 对象字面量(Object Literal):通过{}
- new Object+动态添加属性;
- new 其他类
4.3. 对象的操作过程
- 获取属性
- 修改属性
- 新增属性
-
删除属性
- delete
4.4. 方括号的用法
方括号运行我们在定义或者操作属性时更加的灵活
4.5. 对象的遍历方式
对象的遍历(迭代):表示获取对象中所有的属性和方法。
Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组;
-
普通的for循环
- Object.keys()
- for...in...
- for...of...(不支持)
五. 内存分配
5.1. 内存概念理解
栈内存/堆内存
原始类型占据的空间是在栈内存中分配的;
对象类型占据的空间是在堆内存中分配的;
值/引用类型的分配
原始类型的保存方式:在变量中保存的是值本身
- 所以原始类型也被称之为值类型;
对象类型的保存方式:在变量中保存的是对象的“引用”
- 所以对象类型也被称之为引用类型;
5.2. 现象的内存表示
六. this的使用
6.1. this到底指向什么
- 默认调用 window
- 对象调用 对象
6.2. this的作用
- 方便在一个方法中, 拿到当前对象的一些属性
内容回顾
一. 创建对象的方式
1.1. 对象字面量
- 弊端: 重复代码
1.2. 工厂函数
- createPerson ->
- 类型Object
- JavaScript面向对象的思维方式
1.3. 构造函数
- 构造函数也称之为构造器(constructor),通常是我们在创建对象时会调用的函数;
- 在其他面向的编程语言里面,构造函数是存在于类中的一个方法,称之为构造方法;
- 但是JavaScript中的构造函数有点不太一样,构造函数扮演了其他语言中类的角色;
function coder(name, age) {}
var c1 = new coder("why", 18)
new操作符:
- 创建一个空的对象;
- 将this指向这个空的对象
- 执行函数体中的代码
- 默认返回创建出来的这个对象
1.4. 类和对象的关系
-
在JavaScript中, 构造函数 -> 类
-
类和对象的关系:
-
类是一系列的描述/图纸
- 你应该具备属性/行为
-
对象是根据类, 具体的创建出来对象
-
-
植物大战僵尸:
- 向日葵/阳光/豌豆/僵尸
- 创建类
- 根据类创建具体的对象
-
编程范式: 面向对象的编程范式
1.5. 构造函数的使用
- 构造函数的使用大驼峰(首字母会大写)
二. 对象的补充
2.1. 全局对象window
- 作用一: 查找变量时, 最终会window头上
- 作用二: JavaScript/浏览器默认提供一些变量/函数/类, 提供到window中
alert()
- 作用三: var定义变量会被添加到window上
2.2. 函数也是一个对象类型
function foo() {}
var bar = foo // 地址
bar()
bar.message = "Hello World"
三. 包装类型
常见的包装类型:String,Number.Boolean.Symbol,BigInt类型
3.1. 奇怪现象(悖论)
- 字符串/数字 原始类型
- 没有属性/方法
- 但是发现可以获取属性/调用方法
原因:
- 默认js引擎会创建一个原始类型对应包装类型的对象
- 获取属性/调用方法
- 销毁对象
3.2. Number包装类型
-
类属性:
-
实例方法:
- toString(base)将数字转成字符串,并且按照base进制进行转化
- toFixed(digitals)格式化一个数字,保留digits位的小数
-
类方法
- Number.parseInt -> parseInt
- Number.parseFloat -> parseFloat
类方法/实例方法:
// 类方法
Number.parseInt()
// 实例方法
123..toFixed(2)
3.3. Math对象使用
- Math是一个对象, 不是构造函数, 所以不能通过new调用
- 常见方法:
- Math.floor:向下舍入取整
- Math.ceil:向上舍入取整
- Math.round:四舍五入取整
- Math.random:生成0~1的随机数(包含0,不包含1)
- Math.pow(x, y):返回x的y次幂
3.4. String包装类型
-
创建方式 new String()
-
length属性 获取字符串的长度
-
访问其中元素
-
使用方法一:通过字符串的索引 str[0]
-
使用方法二:通过str.charAt(pos)方法
-
它们的区别是索引的方式没有找到会返回undefined,而charAt没有找到会返回空字符串;
-
遍历
-
普通的for循环
-
for..of方式
- 可迭代对象
- 字符串/数组
-
-
字符串不可变性
-
实例方法:
-
toUpperCase() 字符转为大写
-
toLowerCase() 字符转为小写
-
indexOf 查找字符串位置
从fromIndex开始,查找searchValue的索引; 如果没有找到,那么返回-1 有一个相似的方法,叫lastIndexOf,从最后开始查找(用的较少)
-
includes 是否包含字符串
从position位置开始查找searchString, 根据情况返回 true 或 false 这是ES6新增的方法;
-
startsWith 以xxx开头
-
endsWith 以xxx结尾
-
repace 替换字符串
-
slice/substring/substr 获取子字符串
-
concat 拼接字符串
-
trim 删除首位空格
-
split 字符串分割
- join
-
3.5. 数组Array使用
3.5.1. 数组的创建
-
认识数组结构
-
创建数组
- []
- new Array()
-
数组基本操作
-
获取元素
- [0]
- at(0)
-
修改元素
arr[0] = "abc"
-
新增/删除
-
3.5.2. 新增/删除/替换元素
-
尾部:
- push 在末端添加元素.
- pop 从末端取出一个元素.
-
首部
- unshift 在首端添加元素,整个其他数组元素向后移动;
- shift 取出队列首端的一个元素,整个数组元素向前前移动;
-
利器
-
splice arr.splice 方法可以说是处理数组的利器,它可以做所有事情:添加,删除和替换元素
-
start
-
deleteCount 要删除元素的个数,如果为0或者负数表示不删除;
- 2
- 0
-
item1/item2 在添加元素时,需要添加的元素
-
-
一. 数组Array
1.1. length属性
1.2. 数组的遍历
- 普通的for
- for in
- for of
1.3. 数组方法-slice-concat-join
-
arr.slice 方法:用于对数组进行截取(类似于字符串的slice方法)。
-
arr.concat方法:创建一个新数组,其中包含来自于其他数组和其他项的值。
-
arr.join方法: 将一个数组的所有元素连接成一个字符串并返回这个字符串。
- split
1.4. 数组中查找某一个元素
-
arr.indexOf方法: 查找某个元素的索引
-
find 和 findIndex 直接查找元素或者元素的索引(ES6之后新增的语法)- 高阶函数
-
hyForEach实现
- 版本一: 传入函数之后, 函数会被回调
- 版本二
- ...
-
hyFind实现
-
lastIndexOf
-
findIndex
-
arr.includes方法:判断数组是否包含某个元素
item/index/arr
1.5. sort-reverse
sort方法也是一个高阶函数,用于对数组进行排序,并且生成一个排序后的新数组
reverse() 方法将数组中元素的位置颠倒,并返回该数组。
1.6. 其他高阶函数
- forEach 遍历数组,并且让数组中每一个元素都执行一次对应的方法;
- filter() 方法创建一个新数组;
- map() 方法创建一个新数组;
- reduce 用于计算数组中所有元素的总和
二. 日期Date
2.1. 日期的表示概念
2.2. Date构造函数
new Date()
new Date("2033")
new Date(timestamp)
new Date(year, month)
2.3. 时间表示方法
- RFC表示
- ISO表示
2.4. 实例方法
- getFullYear()
- getMonth()
- getDate()
- ....
-
- getFullYear():获取年份(4 位数);
- getMonth():获取月份,从 0 到 11;
- getDate():获取当月的具体日期,从 1 到 31(方法名字有点迷);
- getHours():获取小时;
- getMinutes():获取分钟;
- getSeconds():获取秒钟;
- getMilliseconds():获取毫秒;
- getDay():获取一周中的第几天,从 0(星期日)到 6(星期六);
自己格式化
- setFullYear
- 自动校正
2.5. 获取时间戳
Date.now()
new Date().getTime()
new Date().valueOf()
+new Date()
2.6. Date.parse(dateString)
- 标准时间
- 非标准时间, 不一定正确
- NaN
三. DOM
文档对象模型(Document Object Model), 简称 DOM,将页面所有的内容表示为可以修改的对象;
3.1. 对DOM理解
- 浏览器将HTML/CSS各个元素抽象模型对象
3.2. DOM Tree
- 学习顺序
额外补充 - 继承理解
一. JavaScript的DOM操作(一)
1.1. 继承的优点
- 代码复用
1.2. 节点导航
- 父节点:parentNode
- 前兄弟节点:previousSibling
- 后兄弟节点:nextSibling
- 子节点:childNodes
- 第一个子节点:firstChild
- 第二个子节点:lastChild
1.3. 元素导航
1.4. table、form导航
- table.rows — 元素的集合;
- table.caption/tHead/tFoot — 引用元素
<caption>,<thead>,<tfoot>; - table.tBodies — 元素的集合
1.5. 获取任意元素方法
- document.getElementsByClassName
- document.getElementById
- document.querySelector()
- document.querySelectorAll()
1.6. Node节点常见的属性
-
nodeType
-
nodeName:获取node节点的名字
-
tagName:获取元素的标签名词;
-
innerHTML: 将元素中的 HTML 获取为字符串形式; /outerHTML:包含了元素的完整 HTML
/textContent:仅仅获取元素中的文本内容
-
nodeValue/data: 用于获取非元素节点的文本内容
1.7. 全局属性-hidden
也是一个全局属性,可以用于设置元素隐藏
二. JavaScript的DOM操作(二)
2.1. attribute分类
-
什么是attribute?属性(attribute)
-
分类:
- 标准的attribute
- 非标准的attribute
2.3. 所有attribute操作
- hasAttribute
- getAttribute
- setAttribute
- removeAttribute
- attributes
2.4. property操作
-
什么叫property
- 对象中的属性称之为property
-
标准的attribute会转成对象模型中的property
-
两个之间会相互影响
2.5. class和style
2.5.1. class和style用法区别
2.5.2. className、classList
- add
- remove
- toggle
- contains
2.5.3. style的用法
- 驼峰写法
- 设置空字符串使用默认值
- cssText(了解)
2.5.4. getComputedStyle方法
2.6. dataset(掌握)
data-* -> dataset
一. 元素操作
1.1. 创建/插入/移除/克隆
- document.createElement()
- append
- prepend
- before
- after
- repaceWith
- remove
- cloneNode
1.2. 元素大小/位置/滚动
- 很多属性
1.3. window大小/滚动
- inner/outer
- html
- scrollX
- scrollY
- scrollBy(x, y)
- scrollTo(x, y)
1.4. 案例练习
1.4.1. 动态创建列表 prompt
1.4.2. 动态展示当前时间
1.4.3. 考拉倒计时展示
-
获取当前时间
-
获取今天的24点
-
计算毫秒时间差
- 转小时
- 转分钟
- 转秒钟
-
计时器中
二. 事件处理
2.1. 事件处理方案
- html里面
- onxxxx属性
- addEventListener
2.2. 事件捕获冒泡
-
事件流的不同传播
- 捕获
- 冒泡
-
addEventListener("click", fn, true)
2.3. 事件对象event
-
type
-
clientX/pageX
-
target/currentTarget
- target: 事件发生的元素
- currentTarget: 当前处理的元素
-
两个方法:
- preventDefault: 阻止默认行为
- stopPropagation: 阻止事件传递
2.4. 事件函数中的this
- 处理的元素
2.5. EventTarget的使用
- addEventListener
- removeEventListener
- dispatchEvent
2.6. 事件委托(delegation)
-
案例一: ul中li点击active
-
案例二: 排他的思想
-
案例三: 多个按钮的区分
- data-*
一. 常见的事件
1.1. 鼠标事件
1.1.1. 常见的事件
1.1.2. mouseenter和mouseover的区别
-
mouseenter:
- 不冒泡
- 进入子元素的时候, 不会有任何反应
-
mouseover
-
会冒泡
-
进入子元素
- 先离开out父元素
- 进入子元素over
- 并且会冒泡给父元素 over
-
1.2. 键盘事件
- keydown
- keypress
- keyup 抬起
区分key
- event.key/code
1.3. 表单事件
- input/change/foucs/blur/reset/submit
1.4. 文档加载
-
DOMContentLoaded
- HTML内容加载完毕,但是外部资源还没有加载完
-
loaded
- HTML所有的内容(包括资源)
二. window定时器
-
setTimeout
- clearTimeout
-
setInterval
- clearInterval
三. 案例实战
3.1. 轮动切换消息
- currentIndex
3.2. 关闭M站头部
- 关闭执行动画
- 监听动画结束
3.3. 侧边栏展示
-
for循环设置backgroundPosition
-
内容的动画
-
方案一: mouseenter
-
方案二: mouseover
- 拿到item不太容易
-
3.4. tabControl的切换
3.5. 王者轮播图的实现
- titleList的切换
- titleList的切换切换上面图片
未实现功能:
-
自动轮播
-
间隔多个title之间的切换, 不要有跳跃的效果
一. 案例实战
1.1. 王者轮播图
1.1.1. 自动轮播图 - 定时器效果
setInterval
1.1.2. 代码的重构
- 将相同的内容抽取到一个函数中
1.1.3. 取消定时器
1.1.4. 默认的效果
-
摆正每个imageItem的位置
-
找到正确的imageItem
-
i === currentIndex
- 设置left0
- 并且添加动画
-
i < currentIndex
- 设置left-100%
- 清除动画
-
i > currentIndex
- 设置left100%
- 清除动画
-
-
原来在active状态的元素不需要清除
- previousIndex记录之前位置的元素
1.2. 书籍购物车
1.2.1. 动态搭建页面
1.2.2. 计算总价格
1.2.3. 删除某一条数据
-
找到对应的rowEl
-
从books, 删除对应的book
-
重新计算价格
一. for循环中变量
1.1. message/i
1.2. 外层btnEl
1.3. this/index
二. 华为商城 - 商品列表
2.1. 界面搭建HTML+CSS
2.2. 动态展示数据resultList
- 方案一: 创建一个个元素
- 方法二: innerHTML
2.3. 服务优惠点击过滤
-
1.获取元素item
-
2.监听item的点击
-
3.监听到
-
切换active
-
获取filterItem添加到数组
-
过滤数组, 获取到过滤之后的数据
- 算法 颜色
-
使用最新的数据 刷新页面(showResultListAction)
-
三. 华为商城 - 轮播图
3.1. 界面搭建HTML+CSS
3.2. 动态展示轮播数据
3.3. 控制(上一个/下一个)
-
1.创建两个变量
- previousIndex
- currentIndex
-
2.修改索引
- 边界判断
-
3.切换active
- previousItemEl移除active
- currentItemEl添加active
3.4. 自动轮播效果
-
开启定时器 startTimer
-
停止定时器 stopTimer
-
默认开启一次
-
监听鼠标进入和离开
- 进入: stopTimer()
- 离开: startTimer()
一. 轮播图
1.1. 指示器的展示
-
指示器界面
-
指示器的切换
- previousIndex
- currentIndex
-
指示器的点击
-
获取点击的索引
- this.index
-
1.2. 无限轮播效果
1.2.1. 克隆first和last的Element
-
cloneNode
-
追加到对应的位置
-
修改left
- last.left = -100%
- first.left = 100*bannerCount
1.2.2. 从原来的切换item, 变成滚动imagesEl
1.2.3. 索引的判断放到滚动之后
1.2.4. 快速修正位置 - 不能有动画
1.3. 增加对定时器的处理
- 离开界面/进入界面对定时器处理
- timer更加严谨
二. 商品列表排序
-
获取排序对应的item
-
监听item的点击
- 切换active
-
获取点击的item的key(信息)
-
对数据进行排序
-
重新再展示数据