笔记

127 阅读15分钟

==和===的区别:

  • ==: 在类型不相同的情况, 会对运算元进行隐式的转换

  * 大部分情况下, 都是转成数字类型 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函数表达式 图片.png

五. 函数式编程中概念

概念一:函数作为一等公民

  • 函数可以赋值给变量

  • 函数也可以传递给另外一个函数

  • 函数也可以作为另外一个函数的返回值

  • 函数也可以存储在别的数据结构中

概念二:函数式编程

  • 函数可以作为头等公民的编程语言,叫做函数式编程的语言;

  • JavaScript就是一种函数式编程语言;

后面三个概念在后续的学习中,我会经常提到和使用:

概念三:函数的回调

  • 将一个作为另外一个函数的参数传入到另外一个函数中;

  • 在另外一个函数中,对于传入的函数进行调用的过程,就叫做函数的回调

概念四:匿名函数

  • 传入一个函数时,如果没有给函数名,也没有定义对应的变量的函数,就叫做匿名函数

概念五:高阶函数

  • foo可以接受另外一个函数参数,那么foo就称之为是一个高阶函数;

  • 如果一个函数有返回另外一个函数,那么这个函数也叫做高阶函数;

foo(function() {

   

})

`

一. 立即执行函数

1.1. 立即执行函数的理解

表达的含义是一个函数定义完后被立即执行

1.2. 立即执行函数的应用

  • 防止全局变量的命名冲突
  • 在btns的点击中, 创建一个作用域保存i的值

1.3. 立即执行函数的其他写法(了解)

图片.png

二. 代码规范

图片.png

三. debug调试技巧(总结)

四. 对象的基本使用

4.1. 认识对象类型

对象类型涉及到JavaScript的各个方面,所以掌握对象类型非常重要;

对象类型是一种存储键值对(key-value)的更复杂的数据类型;

4.2. 对象的创建方式

  1. 对象字面量(Object Literal):通过{}
  2. new Object+动态添加属性;
  3. new 其他类

4.3. 对象的操作过程

  • 获取属性

图片.png

  • 修改属性

图片.png

  • 新增属性

图片.png

  • 删除属性

    • delete

图片.png

4.4. 方括号的用法

方括号运行我们在定义或者操作属性时更加的灵活

图片.png

4.5. 对象的遍历方式

对象的遍历(迭代):表示获取对象中所有的属性和方法。

Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组;

  • 普通的for循环

    • Object.keys()

图片.png

  • for...in...

图片.png

  • 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(信息)

  • 对数据进行排序

  • 重新再展示数据