第二周

71 阅读24分钟

函数与解析

声明式函数在被定义前 调用
fn() 
function fn(){ 程序代码 }

作用域

<!-- 面试题 --> 
全局作用域 ( script内书写的代码 )
在全局作用域中创建的变量叫做全局变量
全局作用域中有一个 提前准备好的 对象 :(window)
console.log(window)
只要在js中创建了全局变量, 就会被添加到window中 / 创建的局部function变量不会,因为属于局部作用域 
<!-- 面试 -->
作用域链 
当访问一个变量时,如果当前作用域内没有,就回会去父级查找,直到查找到最顶级作用域, 
找到就直接使用, 找不到报错. 
局部作用域 ( js中 ,只有函数能创建局部作用域 )
只可以在此作用域中执行, 在此作用域外部不能被执行. 
function fn (){ 
    var sum = '这是局部作用域,不调用不可以执行'
    console.log(sum) 
} 
// 除非调用 
fn()
// 此时也不能调用,因为sum只能在函数内使用 
console.log(sum)

作用域链赋值规则

再给变量赋值时,会首先在当前作用域查找这个变量,如果找到就直接赋值,停止查找 
否则就一级一级向上查找. 
如果全局作用域内也找不到,就会创建一个变量然后赋值.

递归函数 (递和归)

*面试官不让用循环的时候 可以用递归* 
还是一个函数 , 在函数本身内部调用自身
function fn(n){
    if( n === 1 ){
        return 1 
    }
    return n * fn(n-1) 
    } 
    fn(100)

什么是对象

一种数据格式,引用数据类型(复杂数据类型)
var object = {键值对1,键值对2,...}*键值对:kay:value*
键值对后用逗号隔开

对象的操作(增删改查)

点语法 
获取到对象内部某一个属性对应的值
conlose.log(obj.某个属性键)
中括号语法(数组语法) 
obj['属性'] = 属性值 

两种方法的差别

作用相同. 
对象属性名有纯数字或特殊符号'!','@',只能使用中括号语法.
中括号语法书写的字符,如果不加引号'',会当作变量使用,
* obj.[name] / obj['name'] *

遍历对象

key: 推荐使用符合变量命名规则 / 也可以使用纯数字或特殊符号 
for...in 循环遍历语句 
for (var i in 要遍历的对象obj){要执行的代码}
有几个键值对就循环几次 打印 i 就是打印每个Key键名 
打印obj[i]就是打印各个键值. 

数组array

引用数据类型(复杂)
存放数据的集合 按数组内的顺序排列
创建数组方式 
字面量形式 var arr = [1,2,3,4,5...]
内置构造函数 var arr = new Array(1,2,3,4,5)*创建有长度的数组5行* 
打印arr.length :数组的长度 

数组索引下标

一个数据在数组中排列在第几的位置 
从0开始算 , 下标不能改变,下标对应的值能改.
通过下表获取值 : arr[2]

遍历数组

拿到数组的每一个成员 - 首先拿到所有下标
for循环 console.log(arr[i]);

冒泡排序

数组排序算法之一 
拿到数组中每一项,前一项和后一项对比,较大的值后挪
将乱序数组调整为从大到小的顺序 

选择排序

交换假设最小数字索引位置和真实最小索引位置

数据类型间的区别

<!-- 面试 --> 
储存 基本数据类型存储的是值 / 引用类型存储的是内存地址
堆 
*复杂数据类型本体存放在堆中,变量名存储在栈内存中*数组、对象、函数
栈 = 存储内存地址
*基本数据类型储存在栈内存中* string、number、undefined、null、booleam
赋值 
基本数据类型:赋值后,两个变量没有任何关系,
复杂数据类型:因为变量存的是内存地址,赋值以后把地址给到了另外一个变量。操作一个变量时,另外一个变量会受影响。*操作同一个空间内的数据* 
比较
基本数据类型:比较的是值 
引用数据类型:比较的是内存地址
传参 
基本数据类型:将值拷贝传递给形参,在函数内修改不影响外部 
引用数据类型:将值拷贝传递给形参,在函数内修改会影响外部

对象 1.认识对象 什么是对象 JS 中的一种数据格式, 对象在 JS 中的数据类型数据为: 引用数据类型(也有喜欢叫 复杂数据类型)

如何向变量中 存储一个 叫做 对象的数据呢?

语法1: var obj = {键值对} 键值对 -> key: value 如果对象内部有多个 键值对, 那么需要使用 逗号 间隔 什么是键值对 (拿 对象 obj 为例子) var obj = { a: 100, b: 200, c: 300, q: 666 } console.log(obj) 在这个对象中, a 为 key, 100 为对应 value 另外一种叫法: a 为 键, 100 为 对应的 值 另外一种叫法: a 为 属性名, 100 为 对应的 属性值 2. 创建对象 创建对象 分为两种方式: (面试官: JS 中创建对象的方式有哪些?) 字面量的形式 (使用频率比较高)

语法: var obj = {键值对} 内置构造函数的创建

语法1: var obj1 = new Object() // 创建空对象 语法2: var obj1 = new Object({a: 1, b: 2}) // 创建一个具有属性或者说具有键值对的 对象 注意: new Object的 O 是大写的, 不是小写 3. 对象的操作(增删改查) 换句话说, 就是对内部的属性的操作

分为两种方式 点语法 中括号语法(数组语法) 一般来说, 大部分场景使用点语法更简单, 有一些特殊场景只能使用 中括号语法

var obj = { a: 1, b: 'qwe', c: true } console.log('原始对象: ', obj)

//1. 点语法---查询: 获取到 对象内部 某一个属性对应的属性值 console.log(obj.a) // 1 console.log(obj.b) // 'qwe'

//2. 点语法---新增: 向对象内部新增一个属性 obj.q = 'QF001' obj.w = 'QF666' console.log('最新的对象: ', obj)

//3. 点语法---修改: 修改对象内部某一个属性对应的属性值 obj.c = false obj.b = 'QF001' console.log('修改属性后的对象: ', obj)

//4. 点语法---删除: 删除对象内部的某一个属性 delete obj.a console.log('删除属性后的 obj: ', obj)

//5. 中括号语法---查询 console.log(obj['a']) // 1 console.log(obj['c']) // true

//6. 中括号语法---新增 //obj['r = 123'] //obj['r'] = 123 obj['w'] = 456 console.log('新增后的 obj: ', obj)

//7. 中括号语法---修改 obj['b'] = 'QF001' obj['c'] = false console.log('修改后的 obj: ', obj)

//8. 中括号语法的删除 delete obj['a'] console.log('删除属性后的 obj: ', obj) 4.两种操作语法的差别 一般大部分情况下, 点语法与中括号语法, 作用相同, 怎么选择都可以, 特殊情况下我们需要使用中括号语法

对象的属性名, 有纯数字或者特殊符号, 这个时候, 就只能使用中括号语法 如果涉及变量相关的时候, 也需要使用中括号 //特殊情况1 var obj = { 100: '我的属性名是 纯数字 100', '!': '我的属性名是 特殊符号 !', '@': '我的属性名是 特殊符号 @' }

// 此时不能使用点语法, 可以使用中括号语法 // console.log(obj.100) // console.log(obj.!) // console.log(obj.@) console.log(obj[100]) console.log(obj['100']) // console.log(obj[!]) // 有问题, 需要将 特殊符号用引号包裹 console.log(obj['!']) console.log(obj['@']) 复制代码 // 特殊情况2 var obj = { a: 1, b: 2, name: 'QF001' }

var myName = 'name' //console.log(obj.myName) //实际的输出结果是 undefined //因为 对象的 点语法, 会将 点 后边的 字符 当成一个 字符串去使用, 而不会当成变量 //拿 obj.myName 举例他会将 myName 当成一个 字符串 去 对象中查找, 有没有一个叫做 myName 的属性名 //找完之后 发现对象中没有这个属性名, 所以打印的值 为 undefined

console.log(obj[myName]) // 'QF001' //中括号语法, 内部书写的字符, 如果不加引号, 会把它当成变量去使用, 所以找到实际的值之后, myName 这个变量对应的值为'name' //所以 obj[myName] 相当于 写了 obj['name'] //所以会去 对象 obj 中 找一个 叫做 name 的属性名, 找到之后 打印在页面 5. for...in遍历对象 for...in 循环遍历对象

for...in: 一个循环语句

对象: 一种数据格式

遍历: 一般我们会说 '遍历对象' / '遍历数组'

'遍历对象' 想办法拿到对象内部所有的 属性名与属性值 语法: for (var i in 要遍历的对象) { 循环要执行的代码 }

var obj = { a: 1, q: 'qwe', t: true, u: undefined } for (var i in obj) { console.log(obj[i]) // 该对象的所有属性值 数组 1.认识数组 数组 是一种数据类型, 他也是属于 引用数据类型(复杂数据类型) 根据字面意思来说, 存放数字的一个组合, 但这样说有点片面了 更完善的说法: 数组是存放一些数据的集合 换句话说: 我们把数据放在一个盒子中, 这个盒子就叫做数组, 注意! 数组内的数据是有顺序的 2.创建数组 分两种方式

字面量的方式

语法: var arr = [1, 2, 3, 'q', 'w', 'e'] 内置构造函数的方式

语法1: var arr = new Array() 创建一个空数组 语法2: var arr = new Array(5) 创建一个有长度的数组 语法3: var arr = new Array(1, 2, 3) 创建一个有内容的数组 3.数组的 length 属性 length 翻译过来就是 长度的意思 代表 这个数组内, 有多少个成员 语法: 数组名.length 4.数组的索引 索引 也有人叫做 下标 就是指一个数据, 在这个数组内排列在第几个 位置上 注意: 在 JS 中, 索引(下标) 是从 0 开始计算的 如果想要获取到数组指定位置的值, 可以通过下标来获取 语法: 数组名[下标] -> 能够获取到这个数组中对应下标的成员具体的值 5. 遍历数组 想办法 拿到 数组的每一个成员 想拿到数组的所有成员, 需要先想办法拿到数组的所有下标 规律: 所有数组的下标都是从0开始的, 然后到 数组.length - 1 结束 var arr = ['b', 'a', 'c', 1, 2, 3] // 需求, 就是根据 arr 这个数组, 拿到他的所有下标 for (var i = 0; i < arr.length; i++) { // console.log(i) // 0 1 2 3 4 5

// 需求: 拿到数组所有的值, 输出在控制台 console.log(arr[i]) } 6. 冒泡排序 属于数组排序的算法之一

其实就是通过一种算法, 将 一个乱序的数组, 调整为指定顺序的数组(从大到小/从小到大) 什么是算法?

解决某一个问题最简单的方式 / 最高效的方式 //准备一个乱序数组 var arr = [9, 3, 6, 2, 4, 1, 8, 5, 7] console.log('原始数组: ', arr)

// 冒泡排序的核心: 对比数组前一项和后一项, 如果前一项的值较大, 那么就往后挪 (这个排序之后是按照从小到大的顺序) for (var i = 0; i < arr.length; i++) { if (arr[i] > arr[i + 1]) { var temp = arr[i] arr[i] = arr[i + 1] arr[i + 1] = temp } } console.log('1 轮冒泡排序后的数组: ', arr) 复制代码 //基础版 var arr = [9, 3, 6, 2, 4, 1, 8, 5, 7] for (var k = 0; k < arr.length; k++) { //console.log("这是第", k + 1, '循环') for (var i = 0; i < arr.length; i++) { //console.log(arr[i], arr[i + 1]) if (arr[i] > arr[i + 1]) { var temp = arr[i] arr[i] = arr[i + 1] arr[i + 1] = temp } } } console.log('基础版冒泡排序后的数组: ', arr)

//优化版 var arr = [9, 3, 6, 2, 4, 1, 8, 5, 7] for (var k = 0; k < arr.length - 1; k++) { //console.log("这是第", k + 1, '循环') for (var i = 0; i < arr.length - 1 - k; i++) { //console.log(arr[i], arr[i + 1]) if (arr[i] > arr[i + 1]) { var temp = arr[i] arr[i] = arr[i + 1] arr[i + 1] = temp } } } console.log('优化版冒泡排序后的数组: ', arr)

//另一个版本 var arr = [9, 3, 6, 2, 4, 1, 8, 5, 7] for (var k = arr.length; k >= 0; k--) { for (var i = 0; i <=k; i++) { if (arr[i] > arr[i + 1]) { var temp = arr[i] arr[i] = arr[i + 1] arr[i + 1] = temp } } } console.log('另一个版本冒泡排序后的数组: ', arr) 7.选择排序 var arr = [9, 8, 7, 6, 5, 4, 3, 2, 1] // 0 1 2 3 4 5 6 7 8

// 第几次循环 假设谁是最小值 和谁交换 内层循环从几开始 //k === 0 1 0 0 1 //k === 1 2 1 1 2 //k === 2 3 2 2 3 for (var k = 0; k < arr.length; k++) { var minIndex = k for (var i = k + 1; i < arr.length; i++) { if (arr[minIndex] > arr[i]) { minIndex = i } }
var temp = arr[k] arr[k] = arr[minIndex] arr[minIndex] = temp } console.log(arr) 8.数据类型之间的区别 数据类型分为两种

基本数据类型(简单数据类型) 引用数据类型(复杂数据类型) 存储 变量的数据存储的地方是 内存中, 内存分为两个

栈内存 堆内存 基本数据类型存储在 栈内存中, 比如: string number undefined null boolean

复杂数据类型, 将数据本体存放在堆内存中, 比如对象或者数组或者函数,然后将指向该内存的地址, 存放在数组名或者对象名或者函数名中

数组/对象/函数 名 存放在 栈内存中

面试官: 数据类型之间有什么区别?

基本数据类型有哪些, 然后他们存储的地方是 栈内存中 引用数据类型有哪些, 然后他们数据本体存放的地方是 堆内存中, 然后变量名存储的位置是 栈内存中 基本数据类型内部存储的是值; 引用数据类型内部存储的是地址 2. 赋值

基本数据类型: 赋值以后, 两个变量之间没有任何关系, 相当于将我自己的某一个东西, 复制一份给你, 然后你的就是你的, 我的就是我的

例子: 我有一张考试卷, 然后我复制一份给你, 然后你在卷子上书写答案, 并不会影响到我自己原本的这张卷子 复杂数据类型: 因为变量内部存储的是指向堆内存的地址, 所以在赋值的时候, 其实是将 这个地址给到了另外一个变量

那么相当于这两个变量存储的是 同一个 钥匙, 所以操作其中一个变量的时候, 会影响另外一个变量 例子: 我房间有一个开门的钥匙, 我将我的钥匙复制一份, 给到你, 那么此时我们两个共同拥有了一个房间的钥匙 此时如果我对房间的布局做了修改, 那么你进入房间的时候你能看到布局的修改 此时如果你将房间的所有东西全都偷走, 那么我进入房间的时候 能看到房间所有东西都被偷走了 var obj1 = { name: 'QF001', age: 18 }

// 这一步相当于将 变量 obj1 内部存储的 "钥匙", 给到了 变量 obj2, 那么此时 obj2 和 obj1 相当于操作的是一个内存空间 var obj2 = obj1

// console.log(obj2) // {name: 'QF001', age: 18}

obj2.name = 'QF666' console.log(obj2) // {name: 'QF666', age: 18} console.log(obj1) // {name: 'QF666', age: 18} var obj1 = { name: 'QF001', age: 18 } var obj2 = { name: 'QF001', age: 18 }

obj2.name = 'QF666'

console.log(obj1.name) // QF001 /**

    1. 创建一个对象 obj1 内部存储的地址假设为 XF001
    1. 创建一个对象 obj2 内部存储的地址假设为 XF002
  • 注意此时两个对象除了长得一模一样之外 毫无关系
  • 也就是说 操作 其中一个对象, 并不会影响另外一个 */ 比较 基本数据类型: 就是 值 的比较 引用数据类型: 比较的时候 比较的是 存储地址 var obj1 = { name: 'QF001', age: 18 } var obj2 = { name: 'QF001', age: 18 }

console.log(obj1 === obj2) // false /**

  • 引用数据类型在对比的时候, 对比的是 地址
  • 而这两个对象的地址完全不同, 所以返回的结果就是 false */

// var num1 = 100 // var num2 = '100' // console.log(num1 === num2) // false

// var arr1 = [1, 2, 3] // var arr2 = arr1

// console.log(arr1 === arr2) // true /**

  • 引用数据类型在对比的时候, 对比的是 地址 因为 他们两个的地址完全相同, 所以返回的结果是 true */ 传参 基本数据类型: 将值拷贝一份传递给形参, 在函数内修改不会影响外界 引用数据类型: 将存储地址赋值给形参, 在函数内修改会影响外界 9.数组的常用方法 push 语法: 数组.push(数据) 作用: 向数组末尾添加数据 返回值: 追加数据后, 数组最新的长度(length) pop 语法: 数组.pop() 作用: 删除数组最后一条数据 返回值: 被删除的数据 unshift 语法: 数组.unshift(数据) 作用: 向数组开头添加数据 返回值: 添加数据后, 数组最新的长度(length) shift 语法: 数组.shift() 作用: 删除数组第一条数据 返回值: 被删除的数据 reverse 语法: 数组.reverse() 作用: 反转数组 返回值: 反转后的数组 sort 语法1: 数组.sort()

作用: 会将数据转换为 字符串后, 一位一位的对比

语法2: 数组.sort(function (a, b) {return a - b})

作用: 会按照数字大小升序排列 语法3: 数组.sort(function (a, b) {return b - a})

作用: 会按照数字大小降序排列 返回值: 排序后的数组 splice 语法1: 数组.splice(开始索引, 多少个)

作用: 截取数组部分内容 语法2: 数组.splice(开始索引, 多少个, 插入的数据1, 插入的数据2, 插入的数据3...)

作用: 截取数组部分内容, 并插入新的数据 返回值: 截取出来的部分内容 组成的 数组 数组的方法 能够改变原数组的 就只有上边说的 7 个 slice 语法: 数组.slice(开始索引, 结束索引)

参数:

包前不包后: 包含开始索引位置的数据, 不包含结束索引位置的数据 不写开始索引, 默认是0; 不写 结束索引, 默认是 数组的length 参数支持写负数, 表示倒数第几个, 其实就是 length + 负数 作用: 截取数组部分内容

返回值: 截取出来的部分内容组成的新数组 面试题: 数组中有两个方法, splice 与 slice, 你能描述一下他们两个的区别吗? 参数含义不同, 然后介绍一下 参数哪里不同 复制代码 splice 会改变原数组, 而 slice 不会 var arr = [1, 2, 3] console.log('原始数组: ', arr)

// 1. push var len = arr.push(500) console.log(len) // 4 console.log(arr) // [1, 2, 3, 500]

// 2. pop var po = arr.pop() console.log(po) // 3 console.log(arr) // [1, 2]

// 3. unshift var len = arr.unshift(666) console.log(len) // 4 console.log(arr) // [666, 1, 2, 3]

// 4. shift var st = arr.shift() console.log(st) // 1 console.log(arr) // [2, 3]

// 5. reverse var newArr = arr.reverse() console.log('newArr: ', newArr) console.log('arr: ', arr)

// 6. sort var arr = [100, 101, 200, 10, '999', 'qwe', '123abc'] console.log('原始数组: ', arr)

var newArr = arr.sort() console.log('newArr', newArr) console.log('arr', arr)

var newArr = arr.sort(function (a, b) {return a - b}) console.log('newArr', newArr) console.log('arr', arr)

var newArr = arr.sort(function (a, b) { return b - a }) console.log('newArr', newArr) console.log('arr', arr)

// 7. splice var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9] // 0 1 2 3 4 5 6 7 8 console.log('原始数组: ', arr)

// 7.1 var newArr = arr.splice(3, 4) // 从 下标3 开始截取, 截取 4 个 成员/数据 console.log('newArr', newArr) // [4, 5, 6, 7] console.log('arr', arr) // [1, 2, 3, 8, 9]

// 7.2 var newArr = arr.splice(2, 3, '数据1', '数据2', '数据3', '数据4', '数据5') // 不管插入多少个数据, 都是从下标2开始的 console.log('newArr', newArr) console.log('arr', arr)

// 8. slice var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9] // 0 1 2 3 4 5 6 7 8 console.log('原始数组: ', arr)

var newArr = arr.slice(3, 4) // 从 下标3 开始截取, 截取到 下标4 console.log('newArr', newArr) // [4] console.log('arr', arr)

var newArr = arr.slice(5) // 不写 结束索引, 相当于 写了数组.length, 所以这里相当于写了 slice(5, arr.length) console.log(newArr) // [6, 7, 8, 9]

/**

  • 此时 开始索引与结束索引都没有填写, 那么 开始索引相当于是写了一个 0, 结束索引相当于写了 数组.length
  •  arr.slice()     相当于写了      arr.slice(0, arr.length)
    

*/ var newArr = arr.slice() console.log(newArr)

var newArr = arr.slice(3, -2) console.log(newArr) // [4, 5, 6, 7] /**

  • arr.slice(3, -2)
  •  slice 这个方法 允许写 负数
    
  •  写负数的时候 就相当于写了 length + 负数
    
  •  arr.slice(3, -2)    ->      arr.slice(3, arr.length + (-2))     -> arr.slice(3, arr.length - 2)
    
  •                                                                  -> arr.slice(3, 9 - 2)
    
  •                                                                  -> arr.slice(3, 7)
    

*/ 10.数组的常用方法2 concat 语法: 原始数组.concat(数组1, 数组2, ...., 数据1, 数据2, ....)

作用: 进行数据拼接, 把数组...数据之类的小括号里的内容, 拼接在原始数组中 返回值: 拼接好的数组 join 语法: 数组.join('连接符')

作用: 使用 "连接符", 把数组内的每一个数据连接成一个字符串 (不写连接符, 默认使用的是 逗号) 返回值: 连接好的字符串 indexOf 语法1: 数组.indexOf(要检查的数据)

作用: 从前到后(从左到右) 检查该数据第一次在该数组内出现 索引 语法2: 数组.indexOf(要检查的数据, 开始索引)

作用: 在开始索引的位置, 按照从左到右的顺序, 检查该数据第一次在该数组内出现的 索引

返回值: 找到数据的情况下, 会将该数据第一次出现的下标(索引)返回

没找到的情况下, 会直接返回一个 -1 备注: 开始索引不写的时候 默认是0 lastIndexOf 语法1: 数组.lastIndexOf(要检查的数据)

作用: 从后向前(从右向左), 检查该数据第一次在该数组内出现的 索引 语法2: 数组.lastIndexOf(要检查的数据, 开始索引)

作用: 在开始索引的位置, 按照从右向左的顺序, 检查该数据第一次在该数组内出现的 索引

返回值: 找到数据的情况下, 返回第一次出现的下标(索引)

没找到的情况下, 直接返回一个 -1 var arr = [1, 1, 2, 2, 3, 3, 0, 4, 0] // 0 1 2 3 4 5 6 7 8 console.log('原始数组: ', arr) // 9. concat var newArr = arr.concat([4, 5, 6], [10, 20], ['a', 'b', 'c'], 'qwer') console.log('newArr', newArr) // [1, 2, 3, 4, 5, 6, 10, 20, 'a', 'b', 'c', 'qwer'] console.log('arr', arr)

//10. join var newArr = arr.join() // 不传递连接符, 默认使用的是 逗号连接 var newArr = arr.join('!') // 使用 ! 将数组内的所有数据拼接成一个 字符串 // console.log(newArr)

// 11. indexOf var num = arr.indexOf(100) // 此时要检查的数据是 数字100, 但是数组中并没有出现过 数字 100, 所以返回值应该是 -1 var num = arr.indexOf(0) // 此时要检查的数据是 数字0, 数字0按照从左到右的顺序, 第一次出现的下标为 6, 所以返回值应该是 6 var num = arr.indexOf(1) // 此时要检查的数据是 数字1, 数字1按照从左到右的顺序, 第一次出现的下标为 0, 所以返回值应该是 0 var num = arr.indexOf(1, 3) // 此时要检查的数据是 数字1, 但是是从下标3的位置开始按照从左往右的顺序查找, 因为后续并没有数字1, 所以此处应该返回 -1 console.log(num)

// 12. lastIndexOf var num = arr.lastIndexOf(3) // 此时按照从右向左的顺序查找, 发现第一次出现的位置是 下标 5 的位置 var num = arr.lastIndexOf(3, 2) // 此时在下标2的位置按照从右向左的顺序查找, 但是此时在数组中后续的位置并没有出现数字3, 所以按照规则, 应该返回 -1 console.log(num) 11.数组遍历的常用方法 forEach 语法: 数组.forEach(function (item, index, origin) {})

item: 数组的每一项 的值 index: 数组的每一项 对应的下标 origin: 原始数组 (了解即可, 一般没人用) 作用: 遍历数组

返回值: 该方法永远没有返回值 (undefined)

map 语法: 数组.map(function (item, index, origin) {}) 三个参数的意义与 forEach 相同 作用: 映射数组 返回值: 返回一个和原数组长度相同的数组, 但是内部数据可以经过我们的映射加工 映射加工: 就是在函数内 以 return 的形式书写 有一道面试题: 数组常用的遍历方法中, 有一个forEach 和 一个 map, 这两个方法有什么区别?

forEach 的作用是用来遍历数组, 而 map 的作用是用来映射数组 forEach 没有返回值, 而 map 是可以有返回值的 filter 语法: 数组.filter(function (item, index, origin) {}) 三个参数的意义与 forEach 相同 作用: 过滤数组 返回值: 返回一个新数组, 内部存储的是原始数组过滤出来的部分内容 过滤条件: 过滤条件以 return 的形式书写 find 语法: 数组.find(function (item, index, origin) {}) 三个参数的意义 与 forEach 相同

作用: 在数组内查找满足条件的第一项

返回值: 找到的数据, 如果没找到返回的是 undefined

查找条件以 return 的形式书写 findIndex 语法: 数组.findIndex(function (item, index, origin) {}) 三个参数的意义 与 forEach 相同 作用: 在数组内查找满足条件的第一项 的下标 返回值: 找到的数据 的下标, 如果没找到返回的是 -1 查找条件以 return 的形式书写 some 语法: 数组.some(function (item, index, origin) {}) 三个参数的意义 与 forEach 相同 作用: 判断数组内是否有一个满足条件 返回值: 一个布尔值 true/false 判断条件以 return 的形式书写 every 语法: 数组.every(function (item, index, origin) {}) 三个参数的意义 与 forEach 相同

作用: 判断数组内是否全都满足条件

返回值: 一个布尔值 true/false

判断条件以 return 的形式书写 reduce 语法: 数组.reduce(function (prev, item, index, origin) {}, init)

prev: 表示初始值或者上一次的运算结果 item: 表示数组的每一项 的值 index: 表示数组的每一项 的下标(索引) origin: 原始数组 作用: 用来实现叠加效果

返回值: 最终叠加的结果

注意:

叠加条件以 return 的形式书写 prev 第一次的值, 如果你传递了 init, 就是 init 的值, 如果没有传递 init, 那么就是 数组[0] 的值 如果传递了 init, 循环执行 数组.length 次, 如果没有传递 init, 循环执行 数组.length - 1 次 var arr = [100, 200, 300, 400, 500, 600] console.log('原始数组: ', arr)

//1. forEach arr.forEach(function (item, index, origin) { console.log(item, index) console.log(origin) })

//2. map var newArr = arr.map(function (item, index, origin) { // console.log(item, index, origin) return item * 2 }) var newArr = arr.map(function (item) { return item * 2 }) console.log('映射出来的数组: ', newArr)

//3. filter var newArr = arr.filter(function (item, index, origin) { return item > 350 // 过滤数组的内容, 只留下 item 大于 350 的成员 }) console.log(newArr)

//4. find var newArr1 = arr.find(function (item, index, origin) { return item > 3500 // 在数组中查找第一个符合条件的成员 }) console.log(newArr1)

//5. findIndex var newArr2 = arr.findIndex(function (item, index, origin) { return item > 3500 }) console.log(newArr2)

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9] console.log('原始数组: ', arr)

//6. some var bo1 = arr.some(function (item, index, origin) { // return item % 2 === 0 // 判断数组内是否有 一个 满足条件的 return item > 500 // 判断数组内是否有 一个 满足条件的 }) console.log(bo1) // true / false

//7. every var bo2 = arr.every(function (item, index, origin) { // return item % 2 === 0 // 判断数组内 是否 全都 满足条件 return item > 0 // 判断数组内 是否 全都 满足条件 }) console.log(bo2)

var arr = [1, 2, 3, 4] console.log('原始数组: ', arr)

// 8. reduce var str = arr.reduce(function (prev, item, index, origin) { return prev + item }, 0) console.log(str) // 10 12.数组塌陷 13.数学方法 在 JS 中 Math 对象给我们提供了操作数据的一些方法(数学的方法)

random 语法: Math.random() 作用: 得到一个随机数, 每次生成的数字都不一样, 但一定是0~1之间的, 包含0, 不包含1, 也就是说最大值可能是 0.99999.... round 语法: Math.round(数字) 作用: 将这个数字(小数), 按照四舍五入的形式变成整数 ceil 语法: Math.ceil(数字) 作用: 将这个数字(小数) 向上取整 floor 语法: Math.floor(数字) 作用: 将这个数字(小数) 向下取整 abs 语法: Math.abs(数字) 作用: 返回这个数字的绝对值 sqrt 语法: Math.sqrt(数字) 作用: 求 平方根、 pow 语法: Math.pow(基数, 幂) 作用: 返回基数的几次幂 max 语法: Math.max(数字1, 数字2, 数字3...) 作用: 返回传入的数字中 最大的哪一个 min 语法: Math.min(数字1, 数字2, 数字3...) 作用: 返回传入的数字中 最小的哪一个 PI 语法: Math.PI 作用: 返回 π 14.JS的严格模式 JS 是一个相对不是很严谨的语言, 在开发的时候一些代码也不是很严格 换句话说严格模式就是对开发的时候, 你写的代码做了一些要求 严格模式的规则 声明变量必须要 var 关键字 函数的形参不可以重复 JS 中默认是没有开启严格模式, 如果想要开启严格模式, 需要手动在代码最开始的位置(script标签内第一行), 写一个字符串 'use strict' 现在的公司的项目中, 基本都是按照严格模式开发的 15.字符集(了解) 计算机只能存储二进制数据 0101010

我们的 大写字母 小写字母 符号之类的内容 都是由 二进制数字组成

或者说我们在敲一个字符的时候, 都有一个对应的编号, 计算机存储的时候存储的是这些编号,

只不过我们看到的时候, 是通过这些编号解析成我们看到的内容

前身: ASCII as key (128) 只够 美国人用英语的使用

国内 推出了一个属于中国的 GBK 国标码 前128位 ASCII码, 后边从129位开始就是汉字

unicode (万国码)

前 128 位还是 ASCII码, 后边开始是各个国家的文字码 八位十六进制编码 容量小, 但是占用内存也小 UTF-8 十六位的十六进制编码 容量大, 但是占用内存也大