JSCORE

RegExp对象

对应小程序视频:小程序->在线->JSCORE->day01 1. new RegExp()…
链接:https://pan.baidu.com/s/1AbCdJ5Soryib7E4fIi_0Tg
提取码:02vw

  1. 回顾:正则表达式:
    (1). 什么是: 正则表达式就是专门规定一个字符串中字符出现的规律的一套规则。
    (2). 何时: 2大类场景
    a. 验证字符串格式
    b. 查找敏感词
  2. 如何在js中创建正则表达式,用于查找和匹配: 2种:
    (1). 标准写法:
    a. var 变量=new RegExp(“正则表达式”, “ig”)
    创建
    正则表达式类型的对象
    “i” - 忽略大小写
    “g”- 全部
    b. 何时: 今后只要正则表达式不是固定的,需要根据其他变量值和数组内容动态生成,只能用new RegExp()
    (2). 简写:
    js地盘 | 正则地盘| js地盘
    a. var 变量=/ 正则 /ig ,其实就是new RegExp的简写。
    b. 问题: //之中是正则表达式的地盘,只能写正则表达式的语法。不认识js的任何语法!
    c. 解决:
    1). 今后,只有写死的正则表达式,才能用//创建。
    比如: 手机号, 身份证号, 邮箱…
    2). 今后,如果正则表达式不是固定的!需要根据其他的变量或数组动态生成!只能用第一种方式拼接字符串!
    3.示例: 查找字符串中符合要求的敏感词:(复习第一阶段JS day08)
    在这里插入图片描述
  3. 示例: 动态替换字符串中规定的敏感词: (复习第一阶段JS day08)
    2_RegExp.html
    在这里插入图片描述
    5.验证:
    对应小程序视频:小程序->在线->JSCORE->day01 1.1 验证字符串格式…
    链接:https://pan.baidu.com/s/14Wk3C3GJwtFr4RAgkwEc_w
    提取码:f2bj
    (1). 什么是: 用正则表达式检查一个字符串的格式是否符合要求
    (2). 如何:
    a. var 验证结果=正则表达式对象.test(要检查的字符串)
    b. 返回值:
    1). 如果要检查的字符串格式符合正则表达式要求,则返回true
    2). 如果要检查的字符串格式不符合正则表达式要求,则返回false
    (3). 坑: test管的很松,只要字符串中包含部分内容和正则表达式匹配,就返回true。而不要求必须从头到尾完全匹配!
    比如: /\d{6}/.test(“abc123456def”) 返回 true
    “abcdef123456” 返回 true
    (4). 解决: 今后,只要验证格式,都在正则//内,前加^,后加$
    (5). 原理: ^表示字符串开头, 表 示 字 符 串 结 尾 和 表示字符串结尾 ^和 一起使用,就有"必须从头到尾完全匹配"的意思
    (6). 示例: 验证密码格式必须是6位数字
    在这里插入图片描述
  4. 既查找每个敏感词的内容,又查找每个敏感词的位置:
    对应小程序视频: 小程序->在线->JSCORE->day01 1.2查找敏感词…
    链接:https://pan.baidu.com/s/1ZrpHP89ks0xOWstXjJtZGg
    提取码:3krj
    (1). 问题: match最大的问题是只能获得敏感词的内容,无法获得敏感词的位置!
    (2). 解决: 今后,只要既想获得敏感词内容,又想获得敏感词位置,都用正则表达式对象的exec()函数
    (3). 如何: var 查找结果=正则表达式对象.exec(包含敏感词的字符串);
    (4). 强调: 如果想让exec()找所有敏感词,那么正则表达式对象必须加g
    (6). 坑: 如果只调用一次exec(),即使正则表达式加了g,也只能返回一个敏感词的内容和位置。无法找到所有敏感词的内容个位置的!
    (7). 解决: 今后,只要希望exec()可以查找到所有敏感词的内容和敏感词的位置,必须反复调用exec()——exec()自动去找下一个敏感词,直到找不到,返回null为止。
    (8). 固定套路:
    var reg=/正则表达式/g;
    do{
    var result=reg.exec(str);
    console.log(result)
    }while(result!=null); //只有本次找到了敏感词(result!=null)时才有必要继续找下一个!
    (8). exec()的返回值:
    a. 如果找到了一个敏感词:
    内容 下标位置
    var result=[
    0: “小红”,
    index: 5
    ]
    1). 如果想获得结果中的敏感词内容:
    标准: result[“0”] 简写: result[0]
    2). 如果想获得结果中敏感词的位置:
    标准: result[“index”] 简写: result.index
    b. 如果没找到敏感词: null
    (9). 示例:
    在这里插入图片描述
    回顾第一阶段数组: js中数组的本质:
  5. 索引数组: 下标为数字的数组
    var arr=[ “亮亮”, “然然”, “东东”]
    0 1 2
    结果:
    [
    0: “亮亮”
    1: “然然”
    2: “东东”
    ]
  6. 关联数组: 下标为自定义的字符串名称的数组
    var ym=[]
    ym[“数学”]=89
    ym[“语文”]=69
    ym[“英语”]=91
    结果:
    [
    数学: 89
    英语: 91
    语文: 69
    ]
  7. 其实,js内存中,只有一种数组:关联数组
    (1). 无论是索引数组,还是关联数组,底层都是"下标:值"的组合
    (2). 无论访问索引数组中的元素,还是访问关联数组中的元素,都可以用一种标准方式来访问:
    数组名[“下标名”] //其中,下标,既可以写数字,又可以写自定义的下标名称。
    (3). 简写:
    a. 如果要访问的元素下标不是数字,而是自定义的字符串,则可简写为:
    数组名.下标名
    b. 如果要访问的元素下标是数字,则不能用.简写!会和数字的小数点冲突!所以,数字下标只能简写为:
    数组名[下标]
  8. 示例: 索引数组和关联数组底层其实都是关联数组
    在这里插入图片描述
    Function
    一. 回顾函数: (复习第一阶段函数)
    对应小程序视频: 小程序->在线->JSCORE->day01 2. 回顾 定义函数 …
    链接:https://pan.baidu.com/s/1KmuVbh7NcgYxveujw8EhvQ
    提取码:evre
  9. 什么是: 程序中保存一段可反复使用的代码片段的程序结构,再起一个名字.
  10. 为什么: 重用!
  11. 何时: 今后,只要一段代码可能被多次反复使用,都要先封装在一个函数中,再调用函数,执行任务
  12. 如何:
    (1). 创建函数
    function 函数名(){
    函数体;
    }
    (2). 调用函数:
    函数名();
  13. 参数:
    (1). 问题: 如果在函数中写死数据,则一个函数只能处理一种情况,不灵活!
    (2). 解决: 今后,只要希望一个函数可以处理多种数据时,都要为函数定义参数
    (3). 什么是参数: 专门接受函数调用时所必须的数据的变量
    (4). 如何: 2步:
    a. 定义函数时,先在()中定义形参变量:
    function 函数名(形参1, 形参2, …){
    //将原来写死的数据,都换成用形参占位
    //然后再编写函数体
    }
    b. 调用函数时,必须按规定传入对应个数和顺序的实参值。
    函数名(实参值1, 实参值2,…)
  14. 返回值:
    (1). 问题: 如果外部程序想继续使用函数的计算结果,继续执行后续操作,则之用console.log()输出到控制台,肯定是无法重用的!
    (2). 解决: 今后,只要函数外的程序想要使用函数的计算结果,继续执行后续操作时,都要为函数定义返回值!
    (3). 什么是: 一个函数计算结果,被抛出到函数外部,可被外部的变量接住,继续使用!
    (4). 如何: 2步:
    a. 定义函数时:
    function 函数名(形参列表){
    函数体;
    return 计算结果
    }
    b. 调用函数时:
    var 变量=函数名(实参值列表)
  15. 总结:
    (1). 如果函数内部必须某些数据才能正常执行时,必须定义形参!
    (2). 如果函数外部的后续程序想继续使用函数的执行结果时,必须定义返回值return。
  16. 示例: 定义一个函数执行任意两个数的加法
    6_function.html
    在这里插入图片描述

创建函数: 3种方式:

对应小程序视频: 小程序->在线->JSCORE->day01 3.1 创建函数三种方式
链接:https://pan.baidu.com/s/1HOebf7yjC6YM9Mn6WQzMWQ
提取码:m457

  1. 用声明方式:

    (1). function 函数名(形参列表){ 函数体; }
    (2). 问题: 以声明方式定义的函数,会被声明提前,缺点是,打乱了程序正常的执行顺序!
    (3). 复习声明提前(hoist):
    a. 在程序开始执行前,
    b. js引擎会先扫描var声明的变量和function声明的函数,
    c. 提前到当前作用域的顶部集中创建
    d. 赋值留在原地!
    e. 然后才开始执行剩余的程序!

  2. 用赋值方式创建函数:
    (1). var 函数名=function(形参列表){ 函数体 }
    (2). 优点:因为不符合声明语法!不会被声明提前,保持了程序原有的执行顺序!
    (3). 结论: 今后只要定义函数,都优先选择赋值方式创建函数
    在这里插入图片描述

  3. 用new来创建函数: ——几乎不用!
    (1). var 函数名=new Function(“形参1”,“形参2”,…,“函数体”)
    (2). 揭示了一个原理:
    a. 函数也是一个引用类型的对象!
    所有小写的function,底层本质都是new Function()
    b. 而函数名只是一个很普通的变量而已!
    c. 函数名变量通过函数对象的地址值,引用着函数对象
    d. 调用函数时,js引擎都是先找到函数名变量,再根据函数名变量中的地址值,找到保存函数内容的函数对象,再读取函数对象中保存的代码段,逐行执行。
    在这里插入图片描述
    (3). 示例: 演示函数和其他类型变量的存储结构:
    在这里插入图片描述

  4. 示例: 函数声明提前鄙视题: 在这里插入图片描述
    三. 重载(overload):
    对应小程序视频: 小程序->在线->JSCORE->day01 4. 重载 overload pay
    链接:https://pan.baidu.com/s/1AONOEBVrl9ak4FN_eKb1nw
    提取码:mchb

四. 匿名函数:
对应小程序视频: 小程序->在线->JSCORE->day01 5. 匿名函数 防止全局污染
链接:https://pan.baidu.com/s/1vYa9CImiJnFrjZv9tgci7g
提取码:3tix

五. 作用域(scope)和作用域链
对应小程序视频: 小程序->在线->JSCORE->day01 6. 简单作用域
链接:https://pan.baidu.com/s/1tZIplx3jqt4onO0sf6qDBw
提取码:w6av

对应小程序视频: 小程序->在线->JSCORE->day01 7. 原理 作用域和作用域链
链接:https://pan.baidu.com/s/18CmRyhKo5N3gVRJkNxR7dQ

六. 闭包:
对应小程序视频: 小程序->在线->JSCORE->day01 8. 闭包 closure 压岁钱
链接:https://pan.baidu.com/s/1lmtetnoxePabk7Mmvao4QA
提取码:k2zh

总结:
2. RegExp对象:
(1). 创建正则表达式对象:
a. 如果正则是固定的:
var reg=/正则/ig
b. 如果正则需要动态生成:
var reg=new RegExp(“正则”,ig)
(2). 验证字符串格式:
var bool=reg.test(str)
reg必须同时前加^后加$
(3). 既查找每个关键词的内容又查找每个关键词的位置:
do{
var arr=reg.exec(str);
if(arr!=null){
获得本次找到的敏感词的内容(arr[0])和位置(arr.index)
}
}while(arr!=null);
3. 函数:
(1). 创建函数三种方式:
a. function 函数名(形参列表){ 函数体; return 返回值 } //会被声明提前,不好
b. var 函数名=function(形参列表){ 函数体; return 返回值 }//不会被声明提前,首选
c. var 函数名=new Function(“形参1”, “形参2”, … , “函数体; return 返回值”)
函数本质:
1). 函数也是一个对象,对象中保存着函数的函数体代码
2). 函数名只是一个普通的变量,函数名通过函数对象地址,引用着函数对象
3). function在底层等效于new Function()
function 函数名(){ … }和var 函数名=function(){}在底层都会被翻译为
var 函数名=new Function(…)
只不过function 函数名(){}是先提前,再翻译
而var 函数名=function(){}是不提前,原地翻译

今日对应小程序视频:
小程序->在线->JSCORE->day01 1. new RegExp()…
链接:https://pan.baidu.com/s/1AbCdJ5Soryib7E4fIi_0Tg
提取码:02vw

小程序->在线->JSCORE->day01  1.1 验证字符串格式...
链接:https://pan.baidu.com/s/14Wk3C3GJwtFr4RAgkwEc_w 
提取码:f2bj 

小程序->在线->JSCORE->day01 1.2查找敏感词...
链接:https://pan.baidu.com/s/1ZrpHP89ks0xOWstXjJtZGg 
提取码:3krj

小程序->在线->JSCORE->day01  2. 回顾 定义函数 ...
链接:https://pan.baidu.com/s/1KmuVbh7NcgYxveujw8EhvQ 
提取码:evre

小程序->在线->JSCORE->day01  3.1 创建函数三种方式
链接:https://pan.baidu.com/s/1HOebf7yjC6YM9Mn6WQzMWQ 
提取码:m457

Function --day02

一. 重载(overload)
小程序->在线->JSCORE->day01 4. 重载 overload pay
链接:https://pan.baidu.com/s/1AONOEBVrl9ak4FN_eKb1nw
提取码:mchb

  1. 问题: 如果一件事,有多种不同的实现逻辑时,需要将不同的实现逻辑封装在多个函数中。但是,如果给每个不同的函数都起不同的名字,极其不方便将来的调用和记忆!
  2. 解决: 今后,只要一件事,根据不同的条件,执行不同的逻辑时,都要用重载来简化。
  3. 什么是: (别的语言)相同函数名,不同形参列表的多个函数,在调用时,可自动根据传入的实参值不同,找到对应的函数版本调用!
    在这里插入图片描述
  4. 问题: js语言根本不允许多个同名函数同时存在!如果多个同名函数同时存在,只有最有一个同名函数能保存下载,会覆盖之前所有同名函数。
  5. 解决: 借助于arguments对象,变通实现
    (1). 什么是arguments对象:
    a. 每个函数中自带的: 不用自己创建,可直接使用——js语言关键字
    b. 专门自动保存所有传入函数的实参值的——内容
    c. 类数组对象——存储结构
    (2). 什么是类数组对象:
    a. 长得像数组的对象
    b. 类数组对象和数组相比:
    1). 相同: 下标; .length; for循环遍历
    2). 不同: 类型不同。
    i. 类数组对象,是Object类型的对象
    ii. 数组,是Array类型的
    iii. 结果: 类数组对象无法使用数组家所有函数
    在这里插入图片描述
    (3). 如何借助arguments变通实现重载效果?
    a. 不要定义多个函数,只定义一个函数,且不要定义任何形参!
    b. 在函数内,通过判断arguments中的实参值个数或实参值内容,决定何时,执行何种不同的逻辑
    (6). 示例: 定义函数实现三种支付方式
    在这里插入图片描述
    二. 匿名函数
    小程序->在线->JSCORE->day01 5. 匿名函数 防止全局污染
    链接:https://pan.baidu.com/s/1vYa9CImiJnFrjZv9tgci7g
    提取码:3tix
  6. 什么是: 在定义函数时,不指定函数名的函数
  7. 何时: 2种:
    (1). 绝大多数回调函数,都用匿名函数
    (2). 避免使用全局变量时,都用匿名函数自调
  8. 回调函数:
    (1). 什么是: 我们自己定义的函数,但是自己不调用,而是交给别的函数,由别的函数自动调用!
    (2). 比如: arr.sort(function(a,b){return a-b})
    ()中的function,虽然是我们自己定义,但是不是我们自己调用:
    因为我们不知道何时调用,调用了几次,每次传的什么参数
    ()中的function,在sort函数内部,根据sort函数的需要自动调用,自动传参。
    (3). 为什么: 节约内存:
    (4). 原理:
    a. 有名称的函数,函数名是一个变量,引用着函数对象。即使函数用完了,今后不用了,也因为变量名的引用,导致有名称的函数无法释放,占用内存,浪费内存!
    b. 匿名函数,没有函数名!就没有变量引用着。所以用完就被释放了
    在这里插入图片描述
  9. 匿名函数自调:
    (1). 问题: 全局变量极其不靠谱:
    a. 将来多人协作开发时,所有人的程序,最终都会放在一起运行!
    b. 如果刚好两个人的代码中都操作了相同名称的全局变量!就会造成全局污染!结果,两个人的功能都无法正常执行!
    c. 结论: 今后所有的项目中,禁止使用全局变量!
    (2). 解决: 今后所有功能的js代码,都要用匿名函数自调包裹起来。
    a. 如何:
    //创建一个临时函数
    (function(){
    功能的原代码——该怎么写就怎么写,不需要做任何改变!
    })();//立刻调用
    强调: 匿名函数自调的前一条相邻的语句和匿名函数自调结束时,必须加";"
    b. 好处:
    1). 如果功能中用到个别变量,也会被圈在匿名函数内,不会成为全局变量!
    2). 功能的原代码,不需要做任何改定!
    (3). 示例: 分别实现两个商品的秒杀倒计时,并避免全局污染
    在这里插入图片描述
    运行结果:
    在这里插入图片描述
    三. 作用域(scope)和作用域链(scopes)
    小程序->在线->JSCORE->day01 6. 简单作用域
    链接:https://pan.baidu.com/s/1tZIplx3jqt4onO0sf6qDBw
    提取码:w6av
  10. 什么是作用域: 一个变量的可用范围
  11. 为什么: 避免不同范围的变量之间互相干扰!
  12. js中包括: 2级作用域:
    (1). 全局作用域:
    a. 什么是: 专门保存所有全局变量和全局函数的范围
    b. 本质: 其实就是window对象。
    c. 特点:
    1). 优点: 可反复使用。
    2). 缺点: 极容易被全局污染!——全班同学共用的一个水杯
    (2). 函数作用域:
    a. 什么是: 在一个function范围内,专门保存局部变量的范围
    b. 特点:
    1). 优点: 不会被外部篡改
    2). 缺点: 不可重用!
    c. 强调: 局部变量包含2种情况:
    1). 在函数内var出的变量
    2). 函数的形参变量虽然没有写var,但是也是局部变量!
  13. 作用域的使用顺序: 就近原则:
    (1). 调用函数时,优先使用函数作用域内的局部变量
    (2). 除非函数中没有创建想用的变量时,才被迫自动去全局找
  14. 示例: 作用域练习:
    在这里插入图片描述
  15. 作用域原理:
    小程序->在线->JSCORE->day01 7. 原理 作用域和作用域链
    链接:https://pan.baidu.com/s/18CmRyhKo5N3gVRJkNxR7dQ
    (1). 定义函数时:
    a. function都相当于new Function,都会在内存中创建一个函数对象,来保存函数中的代码段。
    b. 每个函数对象身上都有一个"好友列表",普通函数的好友列表中只有两个格子。
    1). 离自己近的格子,暂时为空,为将来某个重要的对象预留
    2). 离自己远的格子,引用着window对象。因为所有函数,最终都可以使用全局作用域中的变量。
    (2). 调用函数时: 先备料
    a. 先创建一个临时的函数作用域对象,集中保存函数中需要用到的所有局部变量。
    b. 并将临时函数作用域对象的地址值保存到函数对象的好友列表中离自己近的格子中。
    (3). 函数执行过程中: 对着"菜谱"做菜
    a. 依次读取出函数中的每条语句开始执行。
    b. 执行过程中,变量的使用顺序: 就近原则: 先局部,后全局。
    1). 优先在函数作用域中查找局部变量使用
    2). 函数作用域对象中没有,才被迫去window中查找变量使用.
    (4). 函数调用后: 收拾
    a. 函数对象会将自己的好友列表中离自己近的格子清空
    b. 导致临时创建的函数作用域对象,没人要了
    c. 导致函数作用域对象,连同作用域中的局部变量一起释放了!
    ——所以,局部变量不可重用!
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  16. 作用域链:
    (1). 什么是: 由多个作用域串联形成的存储结构
    (2). 其实,上图中的"好友列表",学名就叫作用域链
    (3). 作用域链保存着一个函数可用的所有变量(局部变量+全局变量)
    (4). 作用域链还控制着变量的使用顺序: 就近原则,先局部后全局
    四. 闭包
    小程序->在线->JSCORE->day01 8. 闭包 closure 压岁钱
    链接:https://pan.baidu.com/s/1lmtetnoxePabk7Mmvao4QA
    提取码:k2zh
  17. 问题: 全局变量和局部变量都有不可兼得的优缺点。
    (1). 全局变量:
    a. 优点: 重用
    b. 缺点: 极其被污染、篡改
    (2). 局部变量:
    a. 优点: 不会被污染
    b. 缺点: 不可重用
  18. 解决: 今后,如果想重用一个变量,还不希望变量被篡改时,都要用闭包来实现。
  19. 如何: 3步:
    (1). 用一个外层函数包裹要保护的变量和使用变量的内层函数
    (2). 外层函数将内层函数返回到外部
    (3). 要使用内层函数的人必须调用外层函数,用变量接住返回出来的内层函数,才能继续使用内层函数。
  20. 示例: 定义一个函数,为小孩儿管理零花钱:
    在这里插入图片描述
  21. 原理: (了解)在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  22. 简化记忆: 只要找3样东西:
    (1). 外层函数: 妈妈
    (2). 内层函数: 孩子
    (3). 外层函数的局部变量: 红包包
  23. 什么是闭包: 外层函数的作用域对象,在外层函数调用后,依然被内层函数引用着,无法释放,形成了闭包!
  24. 一句话概括,闭包如何形成的:外层函数的作用域对象,在外层函数调用后,依然被内层函数引用着,无法释放
  25. 闭包的缺点: 闭包产生的内层函数比普通函数多占用一块内存空间——外层函数的作用域对象.
  26. 解决: 如果一个闭包结构不再使用后,记得尽快手动释放!
    只要将引用内层函数的变量赋值为null->内层函数就释放了->外层函数的作用域对象也就释放了!
    比如: pay=null
    在这里插入图片描述

面向对象

一. 什么是面向对象:

  1. 问题: 程序中,要管理的数据变的越来越多时,如果还是随意的零散的管理,极其不便于维护的
  2. 解决: 今后,只要大量数据的维护,都要用面向对象的思想。
  3. 什么是面向对象: 在程序中,先用对象结构集中保存现实中一个事物的属性和功能。然后,再按需使用保存好的事物的属性和功能。
  4. 为什么: 极其便于大量数据的管理和维护。
  5. 何时: 今后几乎所有的程序都用面向对象方式开发的!
  6. 如何: 3步/3大特点: 封装,继承,多态

二. 封装:
对应小程序视频:小程序->在线->JSCORE->day02 1. 用{}创建对象 this
链接:https://pan.baidu.com/s/1DtQRS_PprkkzZ3vAhiTg1g 提取码:p3nu

  1. 什么是: 创建一个对象结构,集中保存现实中一个事物的属性和功能。
  2. 为什么: 便于大量数据的管理和维护
  3. 何时: 今后只要使用面向对象的思想开发,都要先封装不同的对象,再按需使用对象中的属性和功能
  4. 如何: 3种:
    (1). 用{}方式创建一个对象:
    a. var 对象名={
    属性名: 属性值,
    属性名: 属性值,
    … : …
    方法名: function(){ … }
    }
    b. 函数 和 方法 区别:
    1). 相同点: 本质是完全一样的!都是function(){ … }
    2). 不同点:
    i. 函数: 特指不包含在任何对象中,可独立使用的function
    ii. 方法: 特指包含在对象中,必须先找到对象,才能调用的function
    c. 如何访问对象中的属性和方法:
    1). 访问对象中的属性: 必须先找到对象,再用.操作符,进入对象中,使用对象的属性
    对象.属性
    2). 访问对象中的方法: 必须先找到对象,再用.操作符,进入对象中,使用对象中的方法。但是必须加()调用
    对象.方法名()
    d. 问题: 对象自己的方法,想使用对象中另一个属性值,直接写属性名,竟然报错!说"xxx属性名未定义"
    e. 原因: 任何不带.前缀的变量,都无权擅自进入某个对象中查找对象中的属性使用!任何不带.前缀的普通变量,只能在函数作用域和全局作用域中查找!
    f. 不好的解决: 在属性名前加上"对象名.",就允许js引擎进入对象内查找属性。
    缺点: 不便于维护!如果外部的对象名修改了,而忘记修改藏的很深的方法中写死的对象名,程序就会出错!
    g. 好的解决: 今后,只要对象中的方法,想使用对象中另一个属性值,都要加this.
    1). 什么是this:
    i. 每个函数中自带的 —— 不用自己创建,就可直接使用
    ii. 专门自动指向正在调用当前方法的.前的对象的
    iii. 关键字 —— 不能改名
    2). 优点: 因为this可以自动获得.前的对象,所以,就算将来对象名改了!this依然可以自动获得!程序就与对象名无关了!便于维护!
    在这里插入图片描述
    h. 示例: 创建一个学生对象,并使用对象中的属性和方法
    在这里插入图片描述
    总结:
    this共有几种情况:4种
    一定不要看定义在哪儿,只看在哪里如何调用
  5. obj.fun() this->.前的obj对象
  6. new Fun() this->new正在创建的新对象
  7. 构造函数.prototype.共有方法=function(){ … }
    this->将来哪个子对象调用这个共有方法,this就指.前的那个子对象。
    谁调用指谁。
  8. 普通函数调用fun(),既没有点,也没有new,this->window(默认)

面向对象

一. 封装:3种
对应小程序视频: 小程序->在线->JSCORE->day02 2. 3. 对象底层是关联数组 …
链接:https://pan.baidu.com/s/1z4PHJlKRUEq-gXApCRVSeA 提取码:q3fi

  1. 用{}只创建一个对象: (已讲)
  2. 用new来创建:
    (1). 如何: 2步:
    a. 先创建一个空对象:var 对象名=new Object()
    b. 再强行向空对象中添加新属性和新方法
    对象名.新属性=值
    对象名.新属性=function(){ … this.属性名 … }
    (2). 揭示: js中所有对象底层其实都是关联数组:
    a. 对象和关联数组都是名值对儿的组合。
    b. 无论访问数组的元素,还是访问对象中的属性,都有两种方式:
    1). 标准写法: 数组名/对象名[“下标名或属性名”]
    2). 简写: 数组名/对象名.下标名或属性名
    3). 特例: 如果要访问的下标名或属性名不是写死的,来自于一个动态变化的变量,则既不能用.,也不能用[""],只能用[变量]
    c. 访问数组或对象中不存在的成员,不会报错,而是返回undefined。
    固定用法: 如何判断一个对象是否包含某个成员: 强行访问
    数组或对象.下标名或属性名!==undefined 说明包含该成员
    ===undefined 说明不包含该成员
    d. 强行给数组或对象中不存在的位置赋值,不会报错,而是自动为数组或对象添加该新的成员。
    固定用法: 如何给数组或对象中添加一个新成员: 强行赋值!
    数组或对象.下标名或属性名=新值!
    e. 都可以用for in循环遍历每个成员
    //in会依次取出数组或对象中每个下标名或属性名
    //保存在in前的变量中
    for(var 变量 in 数组或对象){
    //可以通过"数组或对象[变量]"方式来访问数组或对象中每个成员
    }
    (3). 示例: 使用new Object()创建对象
    在这里插入图片描述在这里插入图片描述
    4). 示例: 克隆一个对象:
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3. 用构造函数反复创建多个相同结构的对象:
对应小程序视频: 小程序->在线->JSCORE->day02 5. 构造函数…
链接:https://pan.baidu.com/s/1igExP1MPetdMYqg5lqbFsA 提取码:o21l
(1). 什么是构造函数: 描述同一类型所有对象的统一结构的函数
(2). 为什么: 重用
(3). 何时: 今后只要想反复创建同一类型的多个相同结构的对象,只是属性值不同而已时,都用构造函数来创建
(4). 如何: 2步
在这里插入图片描述

(5). 原理: new做了4件事: 
a. 先创建一个新的空对象: 
b. ?
c. 调用构造函数,传入属性值: 
	1). new会将所有this都吸引到正在创建的新对象身上
	2). 在构造函数内部: 
		this.属性名=属性值
		↓
		新对象.属性名=属性值
		通过强行赋值的方式,将新属性和新方法强行添加到新对象中
d. new会返回新对象地址,保存到=左边的变量中!

在这里插入图片描述
(6). 示例: 使用构造函数反复创建多个学生对象:
在这里插入图片描述
二. 继承:
对应小程序视频: 小程序->在线->JSCORE->day02 6. 继承 原型对象 prototype
链接:https://pan.baidu.com/s/1r88Efviw6G_R3hLph-xe7w 提取码:iqt6
4. 问题: 如果将方法定义放在构造函数内,那么每创建一个新对象,都会重复创建相同方法的副本——浪费内存!
5. 解决: 今后,只要多个子对象,都要使用一个共同的功能时,都要用继承方式来实现!
6. 什么是继承: 父对象中的成员,子对象无需重复创建,就可直接使用!
7. 如何: js中都是采用继承原型对象的方式来实现继承
(1). 什么是原型对象(prototype):每种类型中,替将来所有的子对象集中保存共有成员的父对象。
(2). 何时: 今后只要多个子对象都需要共用一个功能时,都要将这个功能添加到原型对象中一份即可!
(3). 结果: 只要保存在原型对象中的成员,所有子对象无需重复创建,就可直接使用
(4). 如何创建原型对象:
a. 原型对象不用自己创建!
b. 只要我们每定义一个构造函数妈妈,都会自动附赠我们一个空的原型对象爸爸。
(5). 如何访问原型对象:
a. 每个构造函数内都自带一个隐藏的prototype属性,指向当前构造函数配对的原型对象。
b. 构造函数.prototype
(6). 如何向原型对象中添加共有成员: 只能强行赋值:
构造函数.prototype.共有成员=新值或function(){ … }
从此!构造函数中就不应该再包含任何方法定义!
所有共有的方法,都要集中添加到原型对象中!
8. 何时继承:
(1). 不用手工设置继承!
(2). 当用new调用构造函数,创建该类型的新对象时,new的第二步会自动设置新对象的_ proto 隐藏属性指向构造函数的原型对象,形成继承关系!
(3). js规定,凡是从
proto 指出的引用关系,就是继承关系!
(4). 结果: 将来使用子对象访问一个成员时: 就近原则,先自己后原型
a. 都会先在子对象自己身体里找,如果找到要用的成员,就优先使用自己身体里的成员
b. 如果自己身体里没有要用的成员,则js引擎会自动延
proto _去父对象原型对象中查找父对象中保存的共有属性。如果在父对象中找到了想用的成员,则子对象一样可以直接用.访问!就和访问自己的成员一模一样!
在这里插入图片描述
9. 示例: 在原型对象中添加intr函数
10.在这里插入图片描述
在这里插入图片描述
7. 自有属性和共有属性:
对应小程序视频: 小程序->在线->JSCORE->day02 7. 自有属性 共有属性
链接:https://pan.baidu.com/s/1Wvx8IXmUjNEkziMrz2g50g 提取码:w12p
(1). 什么是:
a. 自有属性: 保存在对象内部,只归当前子对象独有的属性
b. 共有属性: 保存在原型对象中,归多个子对象共有的属性
(2). 相同: 获取属性值的方式完全一样!都可:
子对象.属性名
(3). 不同: 修改属性值时:
a. 如果要修改子对象的自有属性: 子对象.自有属性=新值
b. 如果要修改原型对象中的共有属性:
1). 错误: 子对象.共有属性=新值
i. 共有属性归所有子对象共有,绝不允许任何一个子对象擅自修改共有属性,否则会牵一发而动全身!
ii. 但是,如果硬用子对象修改共有属性,js也会自动变通执行:
不会修改共有属性,而是在当前子对象中添加一个和共有属性同名的自有属性。
iii. 从此!因为lilei有了自有的className属性,就不会再和其它对象共用共有className属性,从此lilei的className就无法再和其它对象保持一致!分道扬镳了!
2). 正确: 今后只要修改共有属性,都必须用"构造函数.prototype"方式来修改!
构造函数.prototype.共有属性=新值
(4). 示例: 获取或修改自有属性和共有属性:
在这里插入图片描述
在这里插入图片描述
8. 内置类型的原型对象:
对应小程序视频: 小程序->在线->JSCORE->day02 8. 11种内置类型…
链接:https://pan.baidu.com/s/139AaFk90zDU4F_5KpLMjoA 提取码:azwu
(1). 问题: 不仅function Student(){},可以用new调用。而且还可以new Array(), new Date(), new RegExp()…为什么这么多东西都可以new呢?!
(2). 其实,凡是可以new的都是一个构造函数。而且,每个可以new的构造函数都有一个与之配对儿的原型对象。比如:
a. new Array():
有一个构造函数: function Array(){ … }
还有一个原型对象: Array.prototype [ sort(), push(), … ]
b. new Date():
有一个构造函数: function Date(){ … }
还有一个原型对象: Date.prototype [ toLocaleString(), setDate(),… ]
(3). 总结: 今后,凡是可以new的,都称为一种"类型",每种类型注定都包含2部分组成:
a. 构造函数: 专门用于创建该类型的一个子对象
b. 原型对象: 专门替所有子对象保存共有的成员
(4). 问题: 如果项目中经常需要用到的一个功能,但是原型对象没有提供!
(5). 解决: 只要自定义一个函数,放入该类型的原型对象中保存,就可保证,当前项目中该类型所有子对象都可共用这个自定义的函数
(6). 如何: 类型名.prototype.共有方法名=function(){
… …
强调: this->将来调用这个共有方法的.前的某个子对象
}
(7). 如何调用: 子对象.共有方法名()在这里插入图片描述

(8). 示例: 为数组类型添加自定义的求和方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
9. 原型链:
对应小程序视频: 小程序->在线->JSCORE->day02 9. 原型链prototype chain
链接:https://pan.baidu.com/s/1aKJv6xQYQaPavtpfk948ug 提取码:7l61
(1). 问题: 原型对象也是对象,那么原型对象有没有父对象?
(2). 答: js中任何对象都有_ proto _属性指向它的父对象
(3). 什么是原型链: 由多级父对象,逐级继承,形成的链式结构,就称为原型链
(4). 一个对象的原型链上:
a. 保存着: 一个对象可以使用的所有属性
b. 控制着: 属性的使用顺序: 就近原则,先自有,后原型
在这里插入图片描述
三. 多态:
对应小程序视频: 小程序->在线->JSCORE->day03 1. 多态override toString()
链接:https://pan.baidu.com/s/1k9S9oYz2W2ca8q1DJN_fkw 提取码:zgrc

  1. 什么是多态: 只要一个函数不同情况下表现出不同的状态。
  2. 包含2种情况:
    (1). 重载(overload): 一件事,传入不同的参数,执行不同的逻辑(已讲)
    (2). 重写(override):
  3. 什么是重写: 如果子对象觉得从父对象继承来的成员不好用!子对象就可以在自己内部创建一个和父对象成员同名的自有成员。
  4. 结果: 从此,这个子对象,优先使用自己的自有成员,不再使用父对象中不好用的共有成员!
  5. 示例: 为Student类型重写toString方法

在这里插入图片描述
四. 自定义继承
对应小程序视频: 小程序->在线->JSCORE->day03 2. 自定义继承…
链接:https://pan.baidu.com/s/1_aUCH1q1gj-aeetL6fWJLg 提取码:cqmy

  1. 问题: 如果父对象中只是个别成员不好用,我可以重写。但是如果整个父对象,几乎都不能用!怎么办?
  2. 解决: 自定义继承关系——换爹
  3. 如何: 2种:
    (1). 只更换一个子对象的父对象:
    a. 子对象._ proto _=新父对象
    b. 问题: _ proto 是浅紫色,意为不太想让人随便使用——不保险
    c. 解决: 今后,只要修改一个子对象的父对象:
    Object.setPrototypeOf( 子对象, 父对象 ) //和
    proto _效果一样!
    设置原型对象的
    设置 子对象 的原型对象为 父对象
    d. 示例: 只修改lilei的父对象: 在这里插入图片描述在这里插入图片描述
    (2). 想批量更换多个子对象的父对象:
    a. 只要更换构造函数的原型对象为新的父对象,则将来创建的所有子对象,都自动继承新的父元素
    构造函数.prototype=新父对象
    b. 问题: 如果在已经创建了子对象之后,才换爹,导致旧子对象无法更换新爹,依然继承旧爹。只有新创建的子对象,才能继承新爹。
    c. 解决: 如果要更换构造函数的原型对象,必须在创建子对象之前更换!
    d. 示例: 更换所有子对象的父对象
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    总结:
    (2). 重载: 今后,一件事,根据传入不同的参数值,动态执行不同的逻辑时,都用重载
    function 一个函数名(不写形参变量){
    //arguments对象自动接住所有实参值
    if(arguments.length0){
    执行一种逻辑
    }else if(arguments.length
    1){
    执行另一种逻辑
    }else{
    执行其它逻辑
    }
    }
    其中arguments是类数组对象: 和数组相比:
    a. 相同点: 也有下标,length属性,也可for循环遍历
    b. 不同点: 不是数组类型,无法使用数组家的函数
    (3). 匿名函数:
    a. 所有回调函数优先使用匿名函数——用完释放,节约内存
    b. 所有js代码都应该保存在匿名函数自调中,禁止使用全局变量,避免全局污染!
    (function(){
    要执行的js代码
    })()
    结果: 匿名函数内的都是局部变量,不会产生全局变量。
    局部变量随匿名函数一起释放。不会污染全局。
    (4). 作用域和作用域链: (跟着视频亲自画图!!!)
    a. 作用域:
    1). 全局作用域:window,保存全局变量
    优: 可重用,缺: 随处可用, 极易被污染
    2). 函数作用域: 保存局部变量
    局部变量包括2中: 函数中var出的变量和形参变量
    优: 仅函数内可用,不会被污染,缺: 不可重用
    3). 函数作用域对象原理:
    i. 每个函数定义时都自带好友列表,好友列表里2个格子,一个是空,一个引用window
    ii. 调用函数时临时创建函数作用域对象保存函数局部变量。并将函数作用域对象的地址保存到函数好友列表中离自己近的格子里。
    iii. 函数执行过程中按就近原则先在自己的函数作用域对象中找局部变量使用。如果找不到,才被迫去全局window中找变量使用.
    iv. 函数调用后,好友列表中离自己近的格子清空,导致函数作用域对象以及内部的局部变量被释放!——所以局部变量不可重用!
    b. 作用域链: 保存一个函数所有可用的作用域对象的链式结构(好友列表)学名就叫作用域链。
    1). 作用域链保存着一个函数可用的所有变量
    2). 作用域链控制着变量的使用顺序。先局部后全局。
    (5). 闭包: (跟着视频亲自画图!!!)
    a. 只要希望给一个函数保护一个可反复使用的专属变量,又防止这个变量被外界篡改时,都用闭包。
    b. 闭包三步:
    1). 用外层函数妈妈包裹要保护的变量和内层函数
    2). 外层函数妈妈用return把内层函数孩子返回到外部
    3). 外部想使用内层函数的人,必须调用外层函数,才能获得return出来的内层函数对象。并将内层函数保存在一个变量中反复使用。
    c. 闭包形成的原因: 外层函数调用后,外层函数的作用域对象被内层函数引用着无法释放,形成了闭包对象
    d. 闭包的缺点: 闭包比一般的函数占用多一块内存——外层函数的函数作用域对象。
    所以,用完闭包后,应该尽快释放:
    保存内层函数的变量=null
  4. 面向对象: 封装 继承 多态
    自己跟着视频,一步一步画图,自己标顺序,知识才能变成自己的
    (1). 封装: 3种:
    a. 用{}创建一个对象:
    var 对象名={
    属性名:属性值,
    … : … ,
    方法名: function(){
    … this.属性名 …
    }
    }
    b. 用new Object():
    1). 2步:
    i. var 对象名=new Object()
    ii. 对象名.属性名=属性值;
    对象名.方法名=function(){ … }
    2). 对象底层也是关联数组:
    i. 都是名值对儿的集合
    ii. 都可用[""]和.方式访问成员。
    如果属性名来自于变量,就只能用[],不要加""
    iii. 访问不存在的属性,都不报错,返回undefined
    判断是否包含某个属性:
    对象.属性名!==undefined
    iv. 强行给不存在的属性赋值,都不报错,而是自动添加该属性
    给对象添加新属性,唯一办法,强行赋值:
    对象名.新属性名=新值
    v. 都可用for in遍历
    c. 只要反复创建多个相同结构的对象都用构造函数:
    1). 2步:
    i. 定义构造函数:
    function 类型名(形参1,形参2, …){
    this.属性名1=形参1;
    this.属性名2=形参2;
    //构造函数中不要再包含方法定义定义!
    }
    ii. 用new 调用构造函数:
    var 对象名=new 类型名(属性值1, 属性值2,…)
    2). new做了4件事:
    i. 创建一个新的空对象
    ii.
    iii. 调用构造函数,传入实参,并自动替换构造函数中的this为new正在创建的新对象。构造函数中,通过强行赋值的方式为新对象添加规定的属性,并保存属性值。
    iv. 返回新对象的地址,保存到=左边的变量中。
    3). 优点: 重用对象结构代码
    4). 缺点: 如果构造函数中包含方法定义,则每次创建新对象都会重复创建相同方法的副本。——浪费内存!
    (2). 继承:
    a. 今后,只要同一类型所有子对象共用的方法和属性值,都要集中保存在构造函数的原型对象中!
    构造函数.prototype.属性名/共有方法名=属性值/function(){ … }
    b. 自有属性和共有属性:
    1). 获取属性值:都可用"子对象.属性名"
    2). 修改属性值:
    i. 自有属性: 子对象.自有属性名=新值
    ii. 共有属性: 构造函数.prototype.共有属性名=新值
    c. 内置类型原型对象:
    1). 11种内置类型/对象: String, Number, Boolean, Array, Date, RegExp, Math(对象), Error, Function, Object, global(对象)
    2). 一种类型=构造函数+原型对象
    i. 构造函数: 创建子对象
    ii. 原型对象: 为所有子对象保存共有成员
    3). 查看该类型共有哪些API: 类型名.prototype
    4). 该类型缺少想用的方法: 类型名.prototype.共有新方法=function(){ … }

d. 原型链: 保存着一个对象可用的所有属性和方法。控制着属性和方法的使用顺序:先自有再共有——就近原则!
(3). 多态: 重点讲重写:如果子对象觉得从父对象继承来的成员不好用,可以在子对象自己内部重写和父对象同名的成员,覆盖父对象的成员,优先使用自己的。
*****面向对象终极总结: 封装,继承,多态
①封装: 创建对象,2种:
如果只创建一个对象: {}
如果反复创建多个相同结构的对象: 构造函数
②继承: 所有子对象共用的属性值和方法,都要放在构造函数的原型对象中
③多态: 重写: 只要觉得从父对象继承来的成员不好用,都在子对象中重写同名成员
④如果觉得这个父对象对象都不好用,可以自定义继承: 2种:
1). 只换一个子对象的父对象: 2种:
i. 子对象.proto=新父对象
ii. Object.setPrototypeOf(子对象, 新父对象)
2). 更换多个子对象的原型对象: 构造函数.prototype=新对象


总结: this 4种
判断this时,一定不要看他定义在哪儿。必须看它在哪里以何种方式调用 4种:

  1. obj.fun() this->点前的obj对象
  2. fun() this->默认指window
  3. new Fun() this->new正在创建的新对象
  4. 类型名.prototype.共有方法=function(){ … }
    this->将来谁调用这个函数,就指谁
    将来调用这个函数的.前的某个子对象

今日对应小程序视频:
小程序->在线->JSCORE->day02
2. 3. 对象底层是关联数组 …
链接:https://pan.baidu.com/s/1z4PHJlKRUEq-gXApCRVSeA 提取码:q3fi

	5. 构造函数...
	链接:https://pan.baidu.com/s/1igExP1MPetdMYqg5lqbFsA 提取码:o21l

	6. 继承 原型对象 prototype
	链接:https://pan.baidu.com/s/1r88Efviw6G_R3hLph-xe7w 提取码:iqt6

	7. 自有属性 共有属性
	链接:https://pan.baidu.com/s/1Wvx8IXmUjNEkziMrz2g50g 提取码:w12p

	8. 11种内置类型..
	链接:https://pan.baidu.com/s/139AaFk90zDU4F_5KpLMjoA 提取码:azwu

	9. 原型链prototype chain
	链接:https://pan.baidu.com/s/1aKJv6xQYQaPavtpfk948ug 提取码:7l61	
小程序->在线->JSCORE->day03  
	1. 多态override toString()
	链接:https://pan.baidu.com/s/1k9S9oYz2W2ca8q1DJN_fkw 提取码:zgrc
	2. 自定义继承...
	链接:https://pan.baidu.com/s/1_aUCH1q1gj-aeetL6fWJLg 提取码:cqmy

ES5: ECMAScript标准的第五个版本 day04

一. 严格模式:
对应小程序视频: 小程序->在线->JSCORE->day03 3. ES5 严格模式…
链接:https://pan.baidu.com/s/1mPjh_e4bucT8H-xlJWWl7Q 提取码:3zyn

  1. 什么是: 比旧的js运行机制要求更严格的运行机制。
  2. 为什么: 因为旧的js运行机制有很多广受诟病的缺陷!
  3. 何时: 今后所有项目,都要在严格模式下开发!
  4. 如何启用严格模式:只要在当前作用域的顶部添加"use strict";,那么,当前作用域内的程序,就运行在严格模式下了!
  5. 严格模式的新规定:
    (1). 禁止给未声明的变量赋值:
    a. 问题: 旧的js中,一个变量即使从未声明过,也可以用=强行赋值!但是!这个变量会被自动创建到全局!——极容易全局污染!
    b. 解决: 只要启用严格模式,就不允许给未声明过的变量赋值!只要赋值就报错!“xxx is not defined”
    c. 示例: 不小心拼错变量名了!
    在这里插入图片描述
    (2). 所有静默失败升级为错误:
    a. 什么是静默失败:旧js中,有些操作不成功!然后还不报错!
    b. 问题: 极其不便于代码的调试
    c. 解决: 启用严格模式后,所有的静默失败,都变成明确的报错!
    d. 优点: 极其便于程序的调试!
    e. 示例: 尝试修改只读属性:
    在这里插入图片描述
    (3). 普通函数调用或匿名函数自调或回调函数中的this不再指向window,而是undefined。
    a. 旧js中,普通函数调用或匿名函数自调或回调函数中,因为之前既没有.又没有new,所以this都默认指向window!——语法规定,没有为什么!
    b. 问题: 经常因为错误的使用this,导致全局污染!
    c. 解决: 启用严格模式,可让普通函数调用和匿名函数自调中的this->undefined,不再指向window
    d. 优点: 避免因为错误使用this导致全局污染

在这里插入图片描述
在这里插入图片描述
(4). 禁用了arguments.callee
a. 什么是arguments.callee: 专门在一个函数内,自动获得当前函数本身的关键字。
b. 为什么: 递归调用时,如果在函数内很深处写死函数名,那么,一旦将来函数名改变,而忘记修改内部写死的函数名!就会立刻出错!
c. 何时: 今后只要递归调用时,都要在当前函数内用arguments.callee代替写死的函数名
d. 优点: 函数内部不用写死函数名,arguments.callee也能自动获得当前函数名——即使修改了函数名,也不用修改内部的函数名!
e. 问题: arguments.callee明明是好东西,为什么严格模式要禁用arguments.callee?
f. 原因: 递归调用效率极低,重复计算量太大!所以,严格模式不建议频繁使用递归调用!
在这里插入图片描述
g. 解决: 绝大多数递归算法,都可以用循环代替!——难度极高!——但是,没有任何重复计算,效率极高!
在这里插入图片描述
h. 总结:
1). 今后,大多数递归算法,虽然有重复计算,但是效率还是可以接收的!我们就首选递归算法。只不过,在函数内部,暂时写死函数名。
2). 除非,递归极大的影响了效率!才被迫寻求用循环方式解决!
i. 示例: 分别使用递归和循环实现计算斐波那契数列中第n个数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
二. 保护对象
对应小程序视频: 小程序->在线->JSCORE->day03 4. 保护对象…
链接:https://pan.baidu.com/s/1hdP8jhURFBlyGQiDRso5lg 提取码:bpuk

  1. 问题: 旧js中,一个对象的属性值或结构,都可随意修改。毫无自保能力!
  2. 解决: ES5标准中提供了保护对象的机制。
  3. 保护单个属性:
    (1). ES5标准中,将对象中每个属性,底层都变成了一个缩微的小对象:
    (2). 每个属性的缩微小对象中都包含4个成员:
    在这里插入图片描述
    (3). 如何查看每个属性的缩微小对象及其内部4个成员:(了解)
    var 缩微小对象=Object.getOwnPropertyDescriptor(对象, “属性名”)
    获得对象自己的属性的描述信息
    (4). 如何修改开关的值来保护对象的属性:
    a. 如果只修改一个属性的开关:
    重新定义属性
    Object.defineProperty(对象名, “属性名”, {
    开关名: true或false,
    … : …
    })
    b. 问题: 我们可以关闭开关,别人同样可以重新打开开关!
    c. 解决: 今后,只要关闭writable开关或enumerable开关时,都要同时关闭configurable:false。就禁止修改前两个开关了!——双保险!
    d. 示例: 使用defineProperty()保护对象属性
    在这里插入图片描述
    e. 问题: Object.defineProperty()一次只能修改一个属性的多个开关。如果对象中,多个属性都需要保护,则需要把Object.defineProperty()重复写很多遍!——繁琐!
    f. 解决: 今后多数情况,一个对象中,都有多个属性需要保护,则应该换成:
    Object.defineProperties(对象, {
    属性名: {
    开关: true或false,
    … : …
    },
    属性名: {
    开关: true或false,
    … : …
    }
    })
    g. 示例: 使用defineProperties()保护对象属性
    在这里插入图片描述
    (5). 问题: 如果用更灵活的自定义规则保护属性值,则开关就无法实现了
    (6). 解决: 今后,只要用自定义的规则,灵活保护属性值时,都要用访问器属性。
    对应小程序视频: 小程序->在线->JSCORE->day03 5. 访问器属性
    链接:https://pan.baidu.com/s/1ApILGAm5mjltr8PXI1JwRA 提取码:bw34
    a. 什么是访问器属性: 自己不实际保存属性值,仅提供对另一个数据属性的保护!——保镖
    b. 如何定义访问器属性: 2步:
    在这里插入图片描述
    1). 为对象添加一个新的半隐藏的属性,将旧对象中要保护的属性值转移到这个新的半隐藏属性中保存:
    Object.defineProperty(对象, “_原属性名”,{
    value: 旧对象.要保护的属性,
    writable: true, 可以修改
    enumerable: false, 实际保存属性值的属性,应该隐姓埋名
    configurable:false //双保险
    })
    2). 为对象添加一个与原属性同名的新访问器属性(替身)代替旧属性:
    Object.defineProperty(对象, “原属性名”,{
    //i. 为替身属性请保镖:
    //①一个保镖必须叫get,是一个函数,专门负责从受保护的_属性中读取出现在的属性值,返回给外部
    get:function(){
    return this._属性名;
    },
    //②一个保镖必须叫set,也是一个函数,专门负责接收外部传来的新值,经过验证后决定是否保存到受保护的_属性中
    set:function(value){ //将来value可自动接到外界传来的新值
    if(value符合要求){
    this._属性=value
    }else{
    不保存,且报错!
    }
    },
    // ii. 因为访问器属性作为替身,必须抛头露面,所以enumerable:true;因为访问器属性替身和保镖不能随意删除,所以configurable:false。
    enumerable:true,
    configurable:false
    //说明: 因为访问器属性不实际保存属性值,所以访问器属性没有value和writable。
    })
    c. 外界如何使用访问器属性: 因为外界根本对访问器属性不知情!所以,外界使用访问器属性替身的用法和使用普通的属性用法完全一样!
    1). 外界想获取访问器属性的属性值时: 对象.属性名
    底层: 当外界想获取访问器属性的属性值时,底层会自动调用访问器属性的get()方法,从实际保存数据的半隐藏的属性中,读取出现在的属性值,return给外部!——信任!
    2). 外界想修改访问器属性的属性值时: 对象.属性名=新值
    底层: 当外界想修改访问器属性的属性值时,底层会自动调用set()方法,并且自动将=右边的新值,传递给set()方法的value形参。在set()内部,先验证value的属性值是否符合要求,再决定是实际保存属性值,还是报错!——信任!
    d. 示例: 使用访问器属性保护年龄属性:
    在这里插入图片描述
    护对象结构: 3个级别
    对应小程序视频: 小程序->在线->JSCORE->day03 6. 保护对象结构 …
    链接:https://pan.baidu.com/s/1vqiNeyiySGkhDjyWHbCD5Q 提取码:zw62
    (1). 防扩展:
    a. 问题: 如果别人觉得你的属性管的太严,不好用!恶意添加一个类似的属性,另起炉灶!
    b. 解决: 可以禁止给对象添加新属性:
    Object.preventExtensions(对象)
    阻止 扩展 们
    (2). 密封: 既防扩展,又防删除
    a. 问题: 对象中几乎所有的属性都禁止删除!那么,难道要给每个属性都加configurable:false吗!?
    b. 解决: 只要密封一个对象,就可以禁止用户删除对象中任何一个属性!
    Object.seal(对象)
    密封
    c. 原理: seal()自动做了2件事:
    1). 自动调用了preventExtensions,禁止添加新属性
    2). 自动为每个对象设置configurable:false,所有属性禁止删除
    d. 强调: 程序中的密封,只禁止添加和删除属性,不禁止修改属性值!属性值还是可以随意修改的!——多数情况,属性值都是可以修改的!
    e. 总结: 今后大多数对象,只要保护到密封(seal)级别,就够了。
    (3). 冻结: 既禁止添加删除属性,又禁止修改属性值——很少用
    a. 如何: Object.freeze(对象)
    冻结
    b. 原理: freeze自动做了三件事:
    1). 也自动调用preventExtensions,禁止扩展新属性
    2). 也自动设置所有属性的configurable:false,所有属性禁止删除
    3). 还自动设置所有属性的writable:false,所有属性禁止修改!
    (4). 示例: 分别使用三个级别保护对象的结构
    在这里插入图片描述
    三. Object.create()
    对应小程序视频: 小程序->在线->JSCORE->day04 2. Object.create()
    链接:https://pan.baidu.com/s/11kKZfHSyFOqWt8SGNR4zZg 提取码:1680
  4. 问题: 通常创建一个子对象,继承父对象,都要通过用new来调用构造函数创建。
    比如: var lilei=new Student(…)
    结果:会新建一个lilei对象,自动继承Student的原型对象
    但是:如果没有构造函数,也想创建子对象,继承父对象?
  5. 解决: 今后,如果没有构造函数,只有一个父对象,也想创建子对象,继承父对象时,都用Object.create()
  6. 如何:
    (1). 基本:只创建一个空对象,继承父对象
    a. var 新子对象=Object.create(父对象)
    b. 原理: 2件事: 完整了new的前2步!
    1). 创建一个新的子对象
    2). 自动设置子对象继承父对象
    c. 问题: 新对象是空的。如果新对象也想有自己的自有属性,怎么办?
    (2). 高级: 创建空对象,继承父对象,并给新对象添加自有属性
    a. var 新对象=Object.create(父对象,{
    //defineProperties中写的格式一样
    新属性名:{
    value:属性值,
    writable:true,
    enumerable:true
    },
    新属性名:{
    value:属性值,
    writable:true,
    enumerable:true
    },
    })
    b. 原理: 3件事: 完整了new的前3步!
    1). 创建一个新的子对象
    2). 自动设置子对象继承父对象
    3). 给新子对象添加自有属性
  7. 示例: 使用Object.create代替new创建子对象继承父对象
    在这里插入图片描述
    总结:
  8. 面向对象: 封装 继承 多态
    自己跟着视频,一步一步画图,自己标顺序,知识才能变成自己的
    (1). 封装: 3种:
    a. 用{}创建一个对象:
    var 对象名={
    属性名:属性值,
    … : … ,
    方法名: function(){
    … this.属性名 …
    }
    }
    b. 用new Object():
    1). 2步:
    i. var 对象名=new Object()
    ii. 对象名.属性名=属性值;
    对象名.方法名=function(){ … }
    2). 对象底层也是关联数组:
    i. 都是名值对儿的集合
    ii. 都可用[""]和.方式访问成员。
    如果属性名来自于变量,就只能用[],不要加""
    iii. 访问不存在的属性,都不报错,返回undefined
    判断是否包含某个属性:
    对象.属性名!==undefined
    iv. 强行给不存在的属性赋值,都不报错,而是自动添加该属性
    给对象添加新属性,唯一办法,强行赋值:
    对象名.新属性名=新值
    v. 都可用for in遍历
    c. 只要反复创建多个相同结构的对象都用构造函数:
    1). 2步:
    i. 定义构造函数:
    function 类型名(形参1,形参2, …){
    this.属性名1=形参1;
    this.属性名2=形参2;
    //构造函数中不要再包含方法定义!
    }
    ii. 用new 调用构造函数:
    var 对象名=new 类型名(属性值1, 属性值2,…)
    2). new做了4件事:
    i. 创建一个新的空对象
    ii. 让新对象继承(_ proto _)构造函数的原型对象
    iii. 调用构造函数,传入实参,并自动替换构造函数中的this为new正在创建的新对象。构造函数中,通过强行赋值的方式为新对象添加规定的属性,并保存属性值。
    iv. 返回新对象的地址,保存到=左边的变量中。
    3). 优点: 重用对象结构代码
    4). 缺点: 如果构造函数中包含方法定义,则每次创建新对象都会重复创建相同方法的副本。——浪费内存!
    (2). 继承:
    a. 今后,只要同一类型所有子对象共用的方法和属性值,都要集中保存在构造函数的原型对象中!
    构造函数.prototype.属性名/共有方法名=属性值/function(){ … }
    b. 自有属性和共有属性:
    1). 获取属性值:都可用"子对象.属性名"
    2). 修改属性值:
    i. 自有属性: 子对象.自有属性名=新值
    ii. 共有属性: 构造函数.prototype.共有属性名=新值
    c. 内置类型原型对象:
    1). 11种内置类型/对象: String, Number, Boolean, Array, Date, RegExp, Math(对象), Error, Function, Object, global(对象)
    2). 一种类型=构造函数+原型对象
    i. 构造函数: 创建子对象
    ii. 原型对象: 为所有子对象保存共有成员
    3). 查看该类型共有哪些API: 类型名.prototype
    4). 该类型缺少想用的方法: 类型名.prototype.共有新方法=function(){ … }

d. 原型链: 保存着一个对象可用的所有属性和方法。控制着属性和方法的使用顺序:先自有再共有——就近原则!
(3). 多态: 重点讲重写:如果子对象觉得从父对象继承来的成员不好用,可以在子对象自己内部重写和父对象同名的成员,覆盖父对象的成员,优先使用自己的。
*****面向对象终极总结: 封装,继承,多态
①封装: 创建对象,2种:
如果只创建一个对象: {}
如果反复创建多个相同结构的对象: 构造函数
②继承: 所有子对象共用的属性值和方法,都要放在构造函数的原型对象中
③多态: 重写: 只要觉得从父对象继承来的成员不要用,都在子对象中重写同名成员
④如果觉得这个父对象对象都不好用,可以自定义继承: 2种:
1). 只换一个子对象的父对象: 2种:
i. 子对象.proto=新父对象
ii. Object.setPrototypeOf(子对象, 新父对象)
2). 更换多个子对象的原型对象: 构造函数.prototype=新对象


  1. 严格模式: “use strict”;
    (1). 禁止给未声明过的变量赋值
    (2). 静默失败升级为错误
    (3). 普通函数调用中的this不指window,而是指undefined
    (4). 禁用arguments.callee
  2. 保护对象:
    (1). 保护属性:
    a. 每个属性包含三个开关:
    1). writable: 控制是否可修改属性值
    2). enumerable: 控制着是否可被for in遍历到,但是只防for in不防.
    3). configurable: 控制
    i. 是否可删除当前属性
    ii. 是否可修改writable和enumerable两个开关
    强调: configurable一旦改为 false,不可逆!
    b. 只修改一个属性的多个开关:
    Object.defineProperty(对象名, “属性名”,{开关: true/false})
    c. 修改多个属性的多个开关:
    Object.defineProperties(对象名,{
    属性名:{ 开关:true/false, … },
    … : …
    })
    d. 如果用自定义的规则保护属性时,只能用访问器属性: 2步:
    Object.defineProperties(对象,{
    //1). 先定义一个隐姓埋名且半隐藏的数据属性:
    _属性名:{
    value: 属性的初始值,
    writable:true,
    enumerable:false,
    configurable:false
    },
    //2). 再定义访问器属性保镖冒名顶替要保护的属性
    属性名:{
    get:function(){
    return this._属性名
    },
    set:function(value){ //value ← 要修改的新属性值
    先验证value
    如果验证通过,this._属性名=value
    否则如果验证未通过,不但不保存新属性值,还会报错
    },
    enumerable:true,
    configurable:false
    }
    })
    外界使用访问器属性时和使用普通属性一样:
    对象.属性名
    外界试图获取访问器属性值时,自动调用get()
    外界试图修改访问器属性值时,自动调用set()
    (2). 保护结构: 3个级别
    a. 防扩展: Object.preventExtensions(对象)
    b. 密封: Object.seal(对象)
    c. 冻结: Object.freeze(对象)
  3. 如果没有构造函数,也想创建子对象,继承父对象:
    var 新子对象=Object.create(父对象,{
    自有属性:{
    value:属性值,
    开关:true或false,
    … :…
    },
    … : { … }
    })
  4. 替换this: 3种:
    (1). 在一次调用函数时,临时替换this,首选:
    函数.call(对象, 实参值,…)
    (2). 临时替换一次this,但是需要打散数组再传参时,被迫改为:
    函数.apply(对象, 数组)
    (3). 创建一个一模一样的新函数并永久绑定this和部分实参值:
    var 新函数名=原函数.bind(对象, 固定实参值, …)

总结: this 5种
判断this时,一定不要看他定义在哪儿。必须看它在哪里以何种方式调用 4种:

  1. obj.fun() this->点前的obj对象
  2. fun()和匿名函数自调和回调函数 this->默认指window
  3. new Fun() this->new正在创建的新对象
  4. 类型名.prototype.共有方法=function(){ … }
    this->将来谁调用这个函数,就指谁
    将来调用这个函数的.前的某个子对象
  5. 访问器属性中的this->访问器属性所在的当前对象本身!

今日对应小程序视频:
小程序->在线->JSCORE->day03
3. ES5 严格模式…
链接:https://pan.baidu.com/s/1mPjh_e4bucT8H-xlJWWl7Q 提取码:3zyn
4. 保护对象
链接:https://pan.baidu.com/s/1hdP8jhURFBlyGQiDRso5lg 提取码:bpuk
5. 访问器属性
链接:https://pan.baidu.com/s/1ApILGAm5mjltr8PXI1JwRA 提取码:bw34
6. 保护对象结构 …
链接:https://pan.baidu.com/s/1vqiNeyiySGkhDjyWHbCD5Q 提取码:zw62
小程序->在线->JSCORE->day04
2. Object.create()
链接:https://pan.baidu.com/s/11kKZfHSyFOqWt8SGNR4zZg 提取码:1680

ES5

一. 替换this
对应小程序视频: 小程序->在线->JSCORE->day04 3. 替换this
链接:https://pan.baidu.com/s/1zZzNvtHMBdWiWY_SsT72xw 提取码:55hz

  1. 问题: 有时,函数内的this指向的对象不是我们需要的!难道我们就只能被动接受?
  2. 解决: 今后只要函数内的this执行的对象不是我们想要的!都有办法更换成我们想要的对象!
  3. 如何:3种:
    (1). 只在一次调用函数时,临时替换一次this:
    a. 要调用的函数.call(替换this的对象)
    b. 原理: call做了2件事:
    1). 先调用函数执行,立刻执行
    2). 将函数内的this都替换为()中想要的对象。
    c. 问题: 有些函数调用时,需要传入实参值!
    d. 解决: 其实,call()中,可以在替换this的对象后,接着写实参值!
    要调用的函数.call(替换this的对象, 实参值1, 实参值2, … )
    e. 原理: call做了3件事:
    1). 先调用函数执行,立刻执行
    2). 将函数内的this都替换为()中想要的对象。
    3). 将实参值传给函数的形参变量!
    f. 示例: 定义计算函数,可以计算每个员工的工资:
    在这里插入图片描述
    在这里插入图片描述
    g. 问题: 有时,函数需要传入多个实参值,但是,多个实参值却是放在一个数组中给的!出现了不一致!
    h. 解决: 都可用apply代替call
    要调用的函数.apply(替换this的对象, 包含实参值数组 )
    i. 原理: apply做了3件事:
    1). 先调用函数执行,立刻执行
    2). 将函数内的this都替换为()中想要的对象。
    3). 先将数组自动拆散为多个实参值,再分别传给函数的多个形参变量!
    j. 示例: 使用apply,先打散数组,再传参:
    在这里插入图片描述
    在这里插入图片描述
    对象,而对象强行要调用函数!用着就很不方便!
    c. 解决: 如果可以创建一个对象专属的函数,永久将this替换为某个对象,则再使用时!就不用反复替换this了!
    d. 如何: 2步:
    1). 创建原函数副本,并永久替换this为指定对象
    var 新函数=原函数.bind(替换this的对象)
    强调: bind()并不会调用函数立刻执行,而是仅仅创建函数的一个一模一样的副本而已。只不过,把新函数中的this永久替换为指定的对象。
    2). 调用新函数,传参,但是无需再call或apply替换this了!
    新函数(传参);
    e. 原理: bind()做2件事:
    1). 创建一个新函数的一模一样的副本
    2). 自动永久替换新函数的this为指定的对象
    f. 强调: 用bind()永久绑定的this,再用call或apply,也是无法重新替换的!
    g. 问题: 有些函数的个别实参值,也是几乎固定不变的!每次调用时,都要反复输入固定不变的实参值,也挺麻烦!
    h. 解决: 其实, bind()不但可以永久绑定this,而且,还可以永久绑定部分实参值!
    i. 如何: 2步:
    1). 先创建函数副本,并永久绑定this和部分实参值
    var 新函数副本=原函数.bind(替换this的对象, 固定的实参值1, …)
    2). 调用函数副本时,只需要传入剩余的可能变化的实参值即可!
    新函数副本(剩余实参值,…)
    j. 原理: bind()做3件事:
    1). 创建一个新函数的一模一样的副本
    2). 自动永久替换新函数的this为指定的对象
    3). 永久绑定部分实参值
    k. 示例: 为lilei创建专属的函数副本,永久绑定this和底薪
    在这里插入图片描述
    在这里插入图片描述
    二. 数组函数:
  4. 判断: 2个:
    对应小程序视频: 小程序->在线->JSCORE->day04 4. every
    链接:https://pan.baidu.com/s/1fFLK7kMOKQwcgDlsD6lHbA 提取码:ocbk
    (1). 判断数组中是否所有元素都符合要求
    a. var 判断结果=数组.every(
    function(当前元素值, 当前下标位置, 当前数组){
    return 判断条件, 只判断当前一个元素是否符合要求!
    }
    )
    b. 原理:
    1). every内部自带for循环,自动遍历当前数组中每个元素
    2). 每遍历一个元素,就自动调用一次回调函数,并且自动按顺序传入三个实参值:
    i. 第一个实参值: 传入当前元素值
    ii. 第二个实参值: 传入当前下标位置
    iii. 第三个实参值: 传入当前数组对象
    3). 在回调函数内部,利用我们提供的自定义的判断条件,判断当前元素是否符合要求!并返回判断结果给every()函数
    4). every()函数拿到判断结果后:
    i. 如果every(),拿到false,说明当前元素不符合要求!就立刻退出循环,并返回整体判断结果为false!说明当前数组中不是所以元素都符合要求的!
    ii. 如果every(),拿到true,说明当前元素符合要求!但是,暂时无法判断后续其它元素是否都符合要去,所以要继续循环判断下一个元素。如果直到循环结束,所有元素经过判断都返回true!every()才返回整体判断结果为true。说明当前数组中所有元素都符合要求!
    在这里插入图片描述
    c. 示例: 判断是否数组中所有元素都是偶数
    在这里插入图片描述
    在这里插入图片描述
    (2). 判断数组中是否包含符合要求的元素
    a. var 判断结果=数组.some(
    function(当前元素值, 当前下标位置, 当前数组){
    return 判断条件, 只判断当前一个元素是否符合要求!
    }
    )
    b. 原理:
    1). some内部自带for循环,自动遍历当前数组中每个元素
    2). 每遍历一个元素,就自动调用一次回调函数,并且自动按顺序传入三个实参值:
    i. 第一个实参值: 传入当前元素值
    ii. 第二个实参值: 传入当前下标位置
    iii. 第三个实参值: 传入当前数组对象
    3). 在回调函数内部,利用我们提供的自定义的判断条件,判断当前元素是否符合要求!并返回判断结果给some()函数
    4). some()函数拿到判断结果后:
    i. 如果some (),拿到true,说明当前元素符合要求!就立刻退出循环,并返回整体判断结果为true!说明当前数组中包含符合要求的元素!
    ii. 如果some(),拿到false,说明当前元素不符合要求!但是,暂时无法判断后续其它元素是否都不符合要求,所以要继续循环判断下一个元素。如果直到循环结束,所有元素经过判断都返回false!some()才返回整体判断结果为false。说明当前数组中不包含符合要求的元素!
    在这里插入图片描述
    c. 示例: 判断一个数组中是否包含奇数:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  5. 遍历: 对数组中每个元素执行相同的操作,包括2个:
    (1). forEach: 单纯代替for循环,遍历数组中每个元素
    对应小程序视频: 小程序->在线->JSCORE->day04 5. forEach …
    链接:https://pan.baidu.com/s/1XIZU0qaGiwyz28JaJXoM4Q 提取码:nmcc
    a. 问题:
    1). for的问题: 语法已经固定了,没有简写的余地了
    2). for in的问题: 语法虽然简单,但是in的遍历,可能超出数字下标的范围,继续遍历父对象中的成员——不保险!
    b. 解决: 今后如果只是想单纯遍历索引数组中每个元素,都可以用forEach代替for和for in
    c. 如何: 数组.forEach(function(当前元素值, 当前下标位置, 当前数组){
    对当前元素值执行相同的操作
    })
    d. 原理:
    1). forEach内部也自带for循环,自动遍历数组中每个元素
    2). 每遍历一个元素,都自动调用一次回调函数,每次调用回调函数时,都自动传入三个值:
    i. 第一个实参值: 传入当前元素值
    ii. 第二个实参值: 传入当前下标位置
    iii. 第三个实参值: 传入当前数组对象
    3). 在回调函数内部,可对当前元素值执行操作。
    e. 示例: 点名:
    在这里插入图片描述
    (2). map: 基于原数组内容,经过修改后,生成一个新数组,原数组保持不变!
    对应小程序视频: 小程序->在线->JSCORE->day04 7. map …
    链接:https://pan.baidu.com/s/11LDWyMvKOdc0yDYlhcIPGA 提取码:cmcm
    a. var 新数组=原数组.map(function(当前元素值, 当前下标, 当前数组){
    return 将当前元素值经过修改后,获得的一个新元素值
    })
    b. 原理:
    1). 先创建一个新的空数组等待。
    2). map内部也自带for循环,自动遍历数组中每个元素
    3). 每遍历一个元素,都自动调用一次回调函数,每次调用回调函数时,都自动传入三个值:
    i. 第一个实参值: 传入当前元素值
    ii. 第二个实参值: 传入当前下标位置
    iii. 第三个实参值: 传入当前数组对象
    4). 在回调函数内部,可对当前元素值执行修改操作,获得新的元素值,返回给map()。
    5). map接到回调函数返回的新元素值之后,会将新元素值,自动添加到新数组中相同的位置上!
    6). 遍历结束!新数组中放满了修改后的新元素值。然后map()就会将新数组返回!
    在这里插入图片描述
    c. 示例: 将原数组中每个元素值*2,获得一个新数组,原数组保持不变
    在这里插入图片描述
  6. 过滤:复制出数组中符合条件的个别元素,放入新数组中返回
    对应小程序视频: 小程序->在线->JSCORE->day04 8. filter
    链接:https://pan.baidu.com/s/11CmX4W4nJkdHOawvGLo2Gg 提取码:bq94
    (1). var 新数组=原数组.filter(function(当前元素值, 当前下标, 当前数组){
    return 判断条件,判断当前元素值是否符合要求
    })
    (2). 强调: filter()是复制出符合要求的元素,原数组保持不变!
    (3). 原理:
    a. 先创建一个新的空数组等待。
    b. filter内部也自带for循环,自动遍历数组中每个元素
    c. 每遍历一个元素,都自动调用一次回调函数,每次调用回调函数时,都自动传入三个值:
    1). 第一个实参值: 传入当前元素值
    2). 第二个实参值: 传入当前下标位置
    3). 第三个实参值: 传入当前数组对象
    d. 在回调函数内部,只判断当前一个元素是否符合要求,并返回判断结果为filter()。
    e. filter接到回调函数返回的判断结果后:
    1). 只有判断结果为true的元素,才会被filter自动追加到新数组中
    2). 如果判断结果为false,则什么也不干,继续遍历下一个元素
    f. 遍历结束!新数组中只放了所有符合要求的元素。然后filter()就会将新数组返回!
    在这里插入图片描述
    (4). 示例: 过滤出数组中的偶数,放入新数组中返回,原数组保持不变
    在这里插入图片描述
  7. 汇总: 对数组中所有元素值进行统计,最终得出一个结论
    (只讲对数组内容求和)
    对应小程序视频: 小程序->在线->JSCORE->day04 9. reduce
    链接:https://pan.baidu.com/s/1-dIVVCNexIwXEvnTCAlHSg 提取码:brbp
    减少
    (1). var 统计结果=数组.reduce(
    //第一个参数,是一个回调函数
    function(临时汇总值, 当前元素值, 当前位置, 当前数组){
    return 将当前元素值汇总到临时汇总值上,形成了新的临时汇总值。
    },
    //第二个参数,是统计的起始值
    起始值
    )
    (2). 原理:
    a. 先创建一个新的变量等待,变量的初始值就是reduce的第二个参数设置的统计起始值。
    b. reduce内部也自带for循环,自动遍历数组中每个元素
    c. 每遍历一个元素,都自动调用一次回调函数,每次调用回调函数时,都自动传入四个值:
    1). 第一个实参值: 将保存在变量中的临时汇总值传给第一个形参
    2). 第二个实参值: 传入当前元素值
    3). 第三个实参值: 传入当前下标位置
    4). 第四个实参值: 传入当前数组对象
    d. 在回调函数内部,将当前元素值汇总到临时汇总值中,获得新的临时汇总值。并将新的临时汇总值,返回给reduce()函数
    e. reduce接到回调函数返回的临时汇总值之后,会将临时汇总值保存到开局时创建的变量中暂存,为继续汇总下一个元素值做准备。
    f. 遍历结束!开局时创建的变量里保存的就是这个数组的统计结果,并返回。
    在这里插入图片描述
    (3). 示例: 对数组中所有元素求和
    在这里插入图片描述

ES6

一. 模板字符串: 复习——将来vue中用的极其多!
对应小程序视频: 小程序->在线->JSCORE->day04 10. 模板字符串
链接:https://pan.baidu.com/s/1qJRajkreGZNE88ZVPxQXlg 提取码:pmpq
(1). 问题: 旧js中,拼接字符串,只能用+,但是+极容易和算术计算的+冲突!
(2). 解决: 今后,只要动态拼接字符串,都要用模板字符串
(3). 什么是: 支持动态拼接内容,支持换行的特殊的字符串。
(4). 如何: 3句话:
a. 整个字符串要用一对儿反引号(键盘左上角esc键正下方)
b. 在内支持换行,支持单引号,支持双引号
c. 如果在字符串中有动态拼接的内容,必须放在${}中
(5). ${}中,到底
a. 能放什么: 变量,三目,运算,有返回值的函数调用,创建对象,访问数组下标——一切有返回值的合法的js表达式,都能放!
b. 不能放什么: 分支(if else if else switch case) 和 循环(for while do while) 和其它没有返回值的js表达式。
(6). 示例: 使用模板字符串动态拼接各种字符串:
在这里插入图片描述
二. let
对应小程序视频: 小程序->在线->JSCORE->day04 11. let
链接:https://pan.baidu.com/s/1qOzv_bGZdkUqmW5oyXhgyA 提取码:b121
(1). 问题: 旧js中,都用var来声明变量,但是var有两个广受诟病的缺陷
a. 声明提前: 破坏了程序正常的执行顺序
b. 不受代码块{}的限制:分支和循环结构的{}内的变量,出了{},依然可以使用!代码块内的变量,就有可能干扰代码块外的变量!
c. 示例: var声明提前和不受代码块{}限制共同造成的问题:
在这里插入图片描述
(2). 解决: 今后所有的变量声明,尽量用let 代替 var。
(3). 优点: 2个
a. let声明的变量不会被声明提前
b. let声明的变量只在最近的{}内有效!出了{}就不能用了!——let让if, else等分支和循环结构的{},也变成作用域——块级作用域。
强调: 假块级作用域,只防let,防不住var。
c. 示例: 使用let解决声明提前和没有块级作用域的问题:
在这里插入图片描述

(4). let的小脾气: 3个
a. 禁止在首次初始化变量之前,提前使用该变量!
b. 相同作用域内,禁止重复let声明相同名称的变量!
c. 即使在全局创建的let变量,在window中也找不到!
d. 示例: 测试let的小脾气:
在这里插入图片描述
(5). let的本质: let底层会被翻译为匿名函数自调!

三. 箭头函数:
对应小程序视频: 小程序->在线->JSCORE->day05 3. 箭头函数arrow
链接:https://pan.baidu.com/s/1VCLP8eUb5vomqQRfwLtSrg 提取码:zunz

四. for of
对应小程序视频: 小程序->在线->JSCORE->day05 4. for of
链接:https://pan.baidu.com/s/1TbGHQZ7GdyVrbbvuHFBJ5A 提取码:7d82

五. 参数增强:3项技能
对应小程序视频: 小程序->在线->JSCORE->day05 5. 参数增强
链接:https://pan.baidu.com/s/1PBJBu2APDk5crjQ7XwG-gQ 提取码:e0kc

总结:
5. 严格模式: “use strict”;
(1). 禁止给未声明过的变量赋值
(2). 静默失败升级为错误
(3). 普通函数调用中的this不指window,而是指undefined
(4). 禁用arguments.callee
6. 保护对象:
(1). 保护属性:
a. 每个属性包含三个开关:
1). writable: 控制是否可修改属性值
2). enumerable: 控制着是否可被for in遍历到,但是只防for in不防for.
3). configurable: 控制
i. 是否可删除当前属性
ii. 是否可修改writable和enumerable两个开关
强调: configurable一旦改为 false,不可逆!
b. 只修改一个属性的多个开关:
Object.defineProperty(对象名, “属性名”,{开关: true/false})
c. 修改多个属性的多个开关:
Object.defineProperties(对象名,{
属性名:{ 开关:true/false, … },
… : …
})
d. 如果用自定义的规则保护属性时,只能用访问器属性: 2步:
Object.defineProperties(对象,{
//1). 先定义一个隐姓埋名且半隐藏的数据属性:
_属性名:{
value: 属性的初始值,
writable:true,
enumerable:false,
configurable:false
},
//2). 再定义访问器属性保镖冒名顶替要保护的属性
属性名:{
get:function(){
return this._属性名
},
set:function(value){ //value ← 要修改的新属性值
先验证value
如果验证通过,this._属性名=value
否则如果验证未通过,不但不保存新属性值,还会报错
},
enumerable:true,
configurable:false
}
})
外界使用访问器属性时和使用普通属性一样:
对象.属性名
外界试图获取访问器属性值时,自动调用get()
外界试图修改访问器属性值时,自动调用set()
(2). 保护结构: 3个级别
a. 防扩展: Object.preventExtensions(对象)
b. 密封: Object.seal(对象)
c. 冻结: Object.freeze(对象)
7. 如果没有构造函数,也想创建子对象,继承父对象:
var 新子对象=Object.create(父对象,{
自有属性:{
value:属性值,
开关:true或false,
… :…
},
… : { … }
})
8. 替换this: 3种:
(1). 在一次调用函数时,临时替换this,首选:
函数.call(对象, 实参值,…)
(2). 临时替换一次this,但是需要打散数组再传参时,被迫改为:
函数.apply(对象, 数组)
(3). 创建一个一模一样的新函数并永久绑定this和部分实参值:
var 新函数名=原函数.bind(对象, 固定实参值, …)
9. 数组函数:
(1). 判断:
a. 判断数组中是否所有元素都符合要求:
var bool=arr.every(function(value,i,arr){
return 判断条件
})
b. 判断数组中是否包含符合要求的元素:
var bool=arr.some(function(value,i,arr){
return 判断条件
})
(2). 遍历:
a. 单纯简化for循环变量原数组中每个元素:
arr.forEach(function(value,i,arr){
对当前元素执行操作
})
b. 保护原数组不变,返回遍历加工后的新数组
var 新数组=arr.map(function(value, i,arr){
return 加工后的一个新元素值
})
(3). 过滤: 复制出数组中符合要求的元素放入新数组返回
var 新数组=arr.filter(function(value,i,arr){
return 判断条件
})
(4). 汇总: 遍历数组中每个元素,经过求和或其他汇总方式,统计出一个最终结论
var 结果=arr.reduce(function(box,value,i,arr){
return box和value计算出的新临时汇总值
}, 起始值)
10. ES6:
(1). 模板字符串: 今后,只要拼接字符串,都用模板字符串代替+:
a. 整个字符串包裹在一对儿反引号...
b. 反引号``中支持换行、""、’'均可使用
c. 反引号中需要动态生成的内容必须放在${}里
d. ${}里:
1). 可以放一切有返回值的合法的变量或js表达式。
2). 不能放程序结构(分支和循环)以及没有返回值的js表达式
(2). let: 今后,阻值变量声明提前或控制变量不要超出块作用域,都用let代替var
a. let的好处:
1). 阻止声明提前
2). 让代码块(分支和循环的{})也变成块级作用域,{}块内的变量出了{}无法使用,不会影响外部
b. let的小脾气:
1). 在同一作用域内禁止重复声明;
2). 禁止提前使用;
3). 在全局声明也不保存在window中

总结: this 5种:

  1. obj.fun() this->点前的obj对象 比如, lilei.intr() this->lilei
  2. new Fun() this->new正在创建的新对象
  3. 类型名.prototype.共有方法=function(){ … }
    this->将来谁调用这个函数,就指谁
    将来调用这个函数的.前的某个子对象
  4. fun() 和 回调函数 和 匿名函数自调 this->默认指window
  5. 访问器属性中的this->当前访问器属性所在的对象

今日对应小程序视频列表:
小程序->在线->JSCORE->day04
3. 替换this
链接:https://pan.baidu.com/s/1zZzNvtHMBdWiWY_SsT72xw 提取码:55hz
4. every
链接:https://pan.baidu.com/s/1fFLK7kMOKQwcgDlsD6lHbA 提取码:ocbk
5. forEach …
链接:https://pan.baidu.com/s/1XIZU0qaGiwyz28JaJXoM4Q 提取码:nmcc
7. map …
链接:https://pan.baidu.com/s/11LDWyMvKOdc0yDYlhcIPGA 提取码:cmcm
8. filter
链接:https://pan.baidu.com/s/11CmX4W4nJkdHOawvGLo2Gg 提取码:bq94
9. reduce
链接:https://pan.baidu.com/s/1-dIVVCNexIwXEvnTCAlHSg 提取码:brbp
10. 模板字符串
链接:https://pan.baidu.com/s/1qJRajkreGZNE88ZVPxQXlg 提取码:pmpq
11. let
链接:https://pan.baidu.com/s/1qOzv_bGZdkUqmW5oyXhgyA 提取码:b121

箭头函数

对应小程序视频: 小程序->在线->JSCORE->day05 3. 箭头函数arrow
链接:https://pan.baidu.com/s/1VCLP8eUb5vomqQRfwLtSrg 提取码:zunz

  1. 问题: 旧的js中,频繁使用函数。但是每次使用函数时,都要写function。
  2. 解决: 今后,定义一个函数,多数情况下,都可用箭头函数代替。
  3. 如何: 3句话:
    (1). 先去掉function,在()和{}之间加=>
    (2). 如果只有一个形参变量,可省略()
    (3). 如果函数体只有一句话,可省略{}
    如果今后的一句话,还是return,则必须省略return!
  4. 示例: 修改旧式的function为箭头函数
    在这里插入图片描述

2_arrow.html
在这里插入图片描述
在这里插入图片描述
5. 问题: 箭头函数最大特点!!!
(1). 箭头函数内部的this->外部的this,内外this保持一致!
(2). 但是,有时,我们不希望内外this相通,比如:
a. 对象中的方法,就不希望方法中的this指向对象外的window
解决: 今后对象中的方法,都可省略":function",但是不要加=>
好处: 既省略了function,又不会影响作用域和this!
b. 构造函数!也不希望内部的this->外层的window!
解决: ES6 class(待续…)
c. 事件处理函数!也不希望内部的this->外层的window!
解决: Vue框架中才学(待续…)
6. 总结:
(1). 如果函数中没有this!或希望内外this相同时,就用箭头函数
(2). 如果函数中有this,且不希望内外this相同时,就不能用箭头函数!
7. 示例: 使用箭头函数简写对象中的方法和回调函数:

  1. 其它重要问题:
    (1). 普通函数改为箭头函数,只影响this,不影响局部变量!局部变量不会变成全局变量!依然只在函数内部有效!
    (2). 箭头函数底层的本质: 相当于.bind(),永久将函数内的this与外部this绑定!今后,即使用call,或apply,也无法更换箭头函数中的this!

for of

对应小程序视频: 小程序->在线->JSCORE->day05 4. for of
链接:https://pan.baidu.com/s/1TbGHQZ7GdyVrbbvuHFBJ5A 提取码:7d82

  1. 问题: 遍历索引数组:
    (1). for的问题: 语法固定,没有可简化的空间
    (2). for in的问题: in不仅遍历数字下标,而且遍历原型对象中的其它共有属性——超范围
    (3). forEach的问题: 是数组家的函数,只能数组家的对象使用。其它类型的对象,比如同为数字下标的类数组对象,就用不了!
  2. 解决: 今后,只要想遍历数字下标的索引数组和类数组对象,都可用for of代替之前所有循环!
  3. 优点:
    (1). 既能遍历索引数组,又能遍历类数组对象——可遍历一切数字下标的东西。
    (2). 语法比之前的都简洁!
  4. 如何: for(var 元素值 of 索引数组/类数组对象){
    对当前元素值执行操作
    }
  5. 原理: of会自动依次取出右边数组中的每个元素值,保存到of前的变量中
    和for in对比,in取出的是下标,不是元素值。
  6. for of的不足:
    (1). 只能从前向后,一个挨一个的遍历。无法改变遍历的顺序和步调!
    (2). 只能获得元素的内容,无法获得元素的位置!
  7. 但是,因为今后绝大多数的遍历,都是从头到尾,挨着遍历,所以今后,for of用的绝对多!
  8. 示例: 定义函数,计算任意多个数字的和

参数增强

小程序->在线->JSCORE->day05: 5. 参数增强
链接:https://pan.baidu.com/s/1PBJBu2APDk5crjQ7XwG-gQ 提取码:e0kc

  1. 参数默认值:
    (1). 何时: 今后,只要希望一个形参变量,即使将来没有传入对应的实参时,也能有一个默认值使用时,就可以用参数默认值。
    (2). 如何: 定义函数时:
    function 函数名(形参1=默认值1, 形参2=默认值2, … ){

    }
    (3). 问题: 只支持前边参数提供,后边参数保持默认的情况
    不支持前边参数希望默认,后边参数提供新值
    (4). 解决: 参数解构(待续…)
    (5). 示例: 定义肯德基点套餐的函数,希望支持各种换菜品的情况

  2. 剩余参数(rest)
    (1). 问题: 箭头函数不支持arguments了!那么,将来在js中如果遇到不确定参数个数的情况时?怎么办?
    (2). 解决: 今后,在新的js中,只要参数个数不确定,都可用剩余参数语法!
    (3). 如何: 定义函数时
    收集所有实参值
    \↓↓↓↓↓↓↓/
    var 函数名=(…自定义数组名)=>{
    //…就会自动将所有的实参值,放入一个自动创建好的数组中保存!
    }
    (4). 问题: 如果有的形参有值,有的形参内容和个数都不确定
    (5). 解决: 其实: …数组名,还可以和其它固定的形参,共同使用!
    第1个实参, 第2个实参, 除1、2实参外所有剩余实参
    ↓ ↓ \↓↓↓↓↓↓↓/
    var 函数名=(固定形参1, 固定形参2, …自定义数组名)=>{

     }
    

    (6). 强调: …自定义数组所获得的数组是一个纯正的数组,可以使用数组家所有的函数!
    (7). 示例: 定义函数计算多个数字的和

  3. 打散数组(spread):
    (1). 问题: apply虽然具有打散数组的功能,但是
    a. apply的本职工作是替换this的,只是顺便能够打散数组。
    b. 所以,如果需求和替换this无关,要使用apply,也被迫随意写第一个实参值,占位!——别扭!
    (2). 解决: ES6,就专门定义了一个只打散数组的方法!
    (3). 如何: 调用函数:
    函数名(…数组)
    (4). 原理: …会先将数组拆散为多个独立的值,再依次传给函数的形参变量。
    (5). 总结: 同样是"…"
    a. 如果在定义函数时的形参列表中用…,意为收集
    b. 如果在调用函数时的实参值列表中用…,意为打散
    (6). 示例: 使用Math.max和Math.min查找数组中的最大值和最小值

(7). 语法糖:
a. 复制一个数组: var arr2=[…arr1];
1). []是创建一个新的空数组的意思
2). …arr1打散原数组,将打散后的所有元素值,放入新数组中
b. 拼接多个数组和元素: var arr3=[…arr1, 元素值, …arr2, 元素值 ]
1). []是创建一个新的空数组等待
2). 先将…arr1和…arr2打散为多个元素值,再和个别写死的元素值,按顺序放入新数组中
c. 克隆一个对象: var obj2={…obj1}
1). {}是创建一个新对象的意思
2). …obj1是先将一个对象,打散为多个属性,再将所有属性,放入新对象中。
d. 拼接多个对象和属性: var obj3={ …obj1, 属性:值, …obj2, 属性:值 }
1). {}是创建一个新的空对象等待
2). 先将…obj1和…obj2打散为多个属性,再和个别写死的属性,放入新对象中保存。——对象中的属性从来不关心前后顺序!只要对象中有这个属性就行!
(8). 使用…语法糖简写实现常用操作:

解构(destruct)

解构(destruct): 从一个大的数组或对象中提取出个别成员单独使用!
对应小程序视频: 小程序->在线->JSCORE->day05 6. 解构(上)
链接:https://pan.baidu.com/s/1Sf3z0jAzTJWsivxHlbRTgA 提取码:v8oo

  1. 数组解构
    (1). 问题: 很多时候,虽然数据放在一个数组中,而我们使用时,经常需要只使用数组中个别位置的数据而已!
    a. 如果每次使用数组中的元素都要"数组名[下标]",太麻烦!
    b. 时间长了,数组下标0,1,2又没有意义,极其不便于将来程序的维护
    (2). 解决: 今后,只要只想用数组中个别元素时,都用数组解构,只提取出个别元素,单独使用!
    (3). 如何: 2步,写在一句话里:
    a. 装扮: 将准备接受元素值的一个一个的变量,放在一个数组的样式中
    [变量1, 变量2,…]
    b. 赋值: =右边,将实际保存数据的数组赋值给左边的数组结构
    =数组
    c. 总结: [变量1, 变量2,…] =数组
    0 1 … 0 1…
    (4). 结果: =右边的数组中相同下标位置的元素值,会自动赋值给=左边的数组中相同下标位置的变量
    变量1=数组[0];
    变量2=数组[1];
    … …
    (5). 示例: 解构出数组中的年,月,日,单独使用

在这里插入图片描述

  1. 对象解构
    (1). 问题: 使用对象中的属性和方法时,总要带着"对象名."前缀,非常麻烦!
    (2). 解决: 如果只是想使用一个大的对象中的个别属性和方法,就可以用对象解构方式提取出个别属性和方法单独使用
    (3). 如何: 还是2步写在一句话中
    a. 先将变量们装扮成对象的样式,且要和实际保存数据的对象结构相同
    var {属性名1: 变量1, 属性名2: 变量2, … }
    b. 赋值:
    =对象
    c. 总结: var {属性名1: 变量1, 属性名2: 变量2, … }=对象
    (4). 结果: =右边的对象中相同属性名的属性值,会自动赋值给=左边的对象结构中相同属性名的变量
    变量1=对象.属性1;
    变量2=对象.属性2;
    … …
    (5). 问题: 如果原对象中属性名已经起的很好了,不想改变对象中原属性名和方法名,又不想在解构时把属性名或方法名重复写2遍
    (6). 解决: 其实=左边的{}中,每个属性可以只写一个名字:
    var {属性名1, 属性名2, …}=对象
    (7). 原理: 一个名字2用,既当属性名,用于配对;又当变量,用作接值
    (8). 示例: 解构出对象中个别属性和方法单独使用
    在这里插入图片描述

  2. 参数解构
    对应小程序视频: 小程序->在线->JSCORE->day05 7. 解构(下)
    链接:https://pan.baidu.com/s/1O96X1b5G6eu96TLhKdBR5w 提取码:dvsn
    (1). 问题: 单靠参数默认值,只支持前边的形参更换,后边的形参保持默认的情况。不支持,更换任意形参,任意形参保持默认的情况——不灵活!
    (2). 解决: 今后,在定义函数时,如果发现将来参数个数不确定,但是又要求实参值必须传给指定的形参变量——有对应关系时,只能用参数解构!
    (3). 如何: 2步:
    a. 定义函数时,要把形参变量们装扮为对象的结构:
    function 函数名({
    属性名1: 形参1,
    属性名2: 形参2,
    … : …
    }){

     }
     不想把属性名和形参名起的不一样,其实也可以只写一个名字: 
     function 函数名({
     //一个名字2用: 
     //既属性名
     //   配对
     //又形参名
     //   接值
     	形参1=默认值, 
     	形参2=默认值, 
     	... 
     }){
     	
     }
    

    b. 调用函数时:
    1). 想传哪些参数就只写哪些参数,不传的参数,一个都不用多写!
    2). 但是,传参时必须也要放在一个对象结构中,且:左边的属性名,应该和定义函数时的形参变量名找到对应才行
    函数({
    形参1: 实参1,
    形参2: 实参2,
    … : …
    })
    (4). 结果:
    a. 如果形参在实参对象中能找到配对儿的属性值,形参就可得到实参值
    b. 如果形参在实参对象中未能找到配对儿的属性值,也不会报错!大不了获得undefined,回来可以用默认值!
    (5). 示例: 定义函数,可以点套餐,并可更换菜品

在这里插入图片描述
在这里插入图片描述

class

对应小程序视频: 小程序->在线->JSCORE->day06: 2. class extends
链接:https://pan.baidu.com/s/1Mr7-MLCVgXPK8AXtSqYaFA 提取码:9kwx

  1. 问题: 旧js中,要想创建一种新的类型,都要创建构造函数和原型对象方法。但是,旧js中构造函数和原型对象方法,是分开写的!不像一家人!——不符合封装的要求
  2. 解决: 今后,只要想创建一种新的类型时,都用class包裹原来的构造函数和原型对象
  3. 如何定义一个class: 3句话:
    (1). 用class{}包裹原来的构造函数和原型对象方法
    (2). 构造函数名/类型名要提升为整个class的名字。原函数统一更名为constructor关键字
    (3). 今后只要放在class中的方法,默认就是保存到原型对象中的方法,且只需要写方法名()即可!
  4. 如何使用class: 和之前使用原型对象和构造函数用法完全一样!
    (1). 先用new创建该类型的子对象
    (2). 用子对象可以访问原型对象中的方法。
  5. 其实,class就是新瓶装旧酒,换汤不换药:
    (1). 除了定义class的步骤稍微有变化之外,创建子对象的方法完全没变!——还是用new 类型名()创建
    (2). 创建出的子对象结构和继承的原理,与旧js中使用构造函数方式创建的子对象,几乎完全一样!——还是__proto__继承原型对象。
  6. 示例: 使用class创建学生类型:
    在这里插入图片描述
    总结: this 5种:
  7. obj.fun() this->点前的obj对象
  8. new Fun() this->new正在创建的新对象
  9. 类型名.prototype.共有方法=function(){ … }
    this->将来谁调用这个函数,就指谁
    将来调用这个函数的.前的某个子对象
  10. fun() 和回调函数 和匿名函数自调 this->默认指window
  11. 访问器属性中的this指访问器属性所在的当前对象

总结:
8. 替换this: 3种:
(1). 在一次调用函数时,临时替换this,首选:
函数.call(对象, 实参值,…)
(2). 临时替换一次this,但是需要打散数组再传参时,被迫改为:
函数.apply(对象, 数组)
(3). 创建一个一模一样的新函数并永久绑定this和部分实参值:
var 新函数名=原函数.bind(对象, 固定实参值, …)
9. 数组函数:
(1). 判断:
a. 判断数组中是否所有元素都符合要求:
var bool=arr.every(function(value,i,arr){
return 判断条件
})
b. 判断数组中是否包含符合要求的元素:
var bool=arr.some(function(value,i,arr){
return 判断条件
})
(2). 遍历:
a. 单纯简化for循环变量原数组中每个元素:
arr.forEach(function(value,i,arr){
对当前元素执行操作
})
b. 保护原数组不变,返回遍历加工后的新数组
var 新数组=arr.map(function(value, i,arr){
return 加工后的一个新元素值
})
(3). 过滤: 复制出数组中符合要求的元素放入新数组返回
var 新数组=arr.filter(function(value,i,arr){
return 判断条件
})
(4). 汇总: 遍历数组中每个元素,经过求和或其他汇总方式,统计出一个最终结论
var 结果=arr.reduce(function(box,value,i,arr){
return box和value计算出的新临时汇总值
}, 起始值)

  1. ES6:
    (1). 模板字符串: 今后,只要拼接字符串,都用模板字符串代替+:
    a. 整个字符串包裹在一对儿反引号...
    b. 反引号``中支持换行、""、’'均可使用
    c. 反引号中需要动态生成的内容必须放在${}里
    d. ${}里:
    1). 可以放一切有返回值的合法的变量或js表达式。
    2). 不能放程序结构(分支和循环)以及没有返回值的js表达式
    (2). let: 今后,阻止声明提前,并将变量限制在代码块{}内,都用let代替var
    a. let的好处:
    1). 阻止声明提前
    2). 让代码块(分支和循环的{})也变成块级作用域,{}块内的变量出了{}无法使用,不会影响外部
    b. let的小脾气:
    1). 在同一作用域内禁止重复声明;
    2). 禁止提前使用;
    3). 在全局声明也不保存在window中
    c. let的原理: 匿名函数自调
    (3). 箭头函数: 今后,几乎所有的function都可用箭头函数简写:
    a. 如何: 3句话:
    1). 去掉function,在()和{}之间加=>
    2). 如果只有一个形参,可省略()
    3). 如果函数体只有一句话,可省略{}
    如果仅有的一句话还是return,必须省略return
    b. 特点: 箭头函数内部的this与外部的this,保持一致。
    c. 今后:
    1). 如果函数中没有this或者恰好希望函数内this与函数外this保持一致时,可用箭头函数简写!
    2). 如果不希望内外this相同时不能使用箭头函数简写。
    (4). for of: 今后只要遍历数字下标的索引数组、类数组对象和字符串,都用for of
    在这里插入图片描述

(5). 参数增强:
a. 参数默认值: 定义函数时最后一个形参不确定有没有实参时
function 函数名(形参1, …, 最后形参=默认值){
… …
}
b. 剩余参数: 定义函数时: 只要多个形参不确定,都用剩余参数
function 函数名(其它形参, …数组名){
//…收集除其它形参外多余的实参值保存到指定数组名的数组中
}
c. 打散数组: 今后调用函数时,只要单纯打散数组再传参时
1). 如何: 函数(…数组)
2). …口诀: 定义函数时…表示收集, 调用函数时…表示打散
3). …语法糖:
i. 复制一个数组: var arr2=[…arr1];
ii. 合并多个数组和元素值: var arr3=[…arr1,值,…arr2,值]
iii. 复制一个对象: var obj2={ … obj1 }
iv. 合并多个对象和属性: var obj3={ …obj1, 属性:值, …obj2, 属性:值 }
(6). 解构:
a. 只要想提取出数组中个别元素值,单独使用时,就数组解构:
[变量1, 变量2]=arr;
b. 只要想提取出对象中个别属性值或方法,单独使用时,就对象解构:
var {属性名也是变量名, 属性名也是变量名}=对象
c. 只要多个参数不确定有没有,又要求实参值必须传给指定的形参时,就参数结构:
定义函数时:
function 函数名({
属性名也是形参名=“默认值”,
属性名也是形参名=“默认值”,
… = …
}){
函数体
}
调用函数时:
函数名({
要修改的形参名: 实参值,
… : … ,
})
(7). class extends
a. 定义class:
class 类型名{
constructor(形参列表){
this.属性名=形参;
… = …;
}
共有方法(){
… this.属性 …
}
}
class的底层原理和用法与旧js构造函数用法完全相同!——新瓶装旧酒
b. 继承: 只要两种类型间包含部分相同的属性结构和方法定义,都要额外定义一个父类型集中保存两种类型相同的属性结构和方法定义。然后再让子类型继承父类型
class 子类型 extends 父类型{
constructor(…){
super(…);
this.属性名=形参;
}
子类型共有方法(){

}
}
两步,两个关键字: extends是继承的意思,super()是调用父类型构造函数,请父类型构造函数帮忙添加相同部分的属性的意思。
(8). Promise: 当多个异步任务必须顺序执行时,就可用promise
a. 前一项任务:
function 前一项任务(){
return new Promise(
function(door){
原异步任务;
原异步任务最后一句话之后door()
}
)
}
b. 调用前一项任务时:
前一项任务().then(下一项任务)
c. 如果下一项任务也返回new Promise对象,则可以继续用.then()相连
前一项任务().the(下一项任务).then(之后任务).then(…)…
d. 前后两个任务间传值:
1). 前一项任务内:
door(一个变量);
//只能传一个变量
//如果传多个值,可放在数组或对象中
2). 后一项任务声明时:
function 后一项任务(形参){ … }
//前一项任务:door()中传什么
//后一项任务:形参就接住什么

day07

class

对应小程序视频: 小程序->在线->JSCORE->day06: 2. class extends
链接:https://pan.baidu.com/s/1Mr7-MLCVgXPK8AXtSqYaFA 提取码:9kwx

  1. 问题: 在定义多个class时,经常发现多个class之间包含部分相同的属性结构和方法定义

  2. 解决: 需要额外定义一个class,替多个class集中保存相同部分的属性和功能

  3. 如何: 2步:
    (1). 先创建一个新的class,集中保存多个class之间相同的属性和方法
    a. 新class的构造函数中,保存多个class相同部分的属性定义
    b. 新class的原型对象中,保存多个class相同部分的方法定义
    c. 问题:
    1). 原来的多个class中不再包含相同部分的属性定义和方法定义,导致,将来创建的子对象中也就缺少了必要的属性和方法
    2). 而且,我们只是新建了一个class,没有设置任何继承关系,所以新class与原多个class之间毫无联系!
    (2). 让原class都继承新class,那么,原class的子对象就可以使用到新class中的属性和方法了!
    a. 让子类型class,继承父类型class: class 子类型 extends 父类型{ … }
    1). 结果: 类似于setPrototypeOf的功能,自动设置了子类型继承父类型。子对象就可使用父类型中的方法了。
    2). 问题: 因为将来创建子对象时,只会new 子类型(),不会自动调用父类型构造函数,所以子对象中,依然没有父类型class中的属性结构
    b. 在子类型构造函数内,手动调用super(实参值,…),相当于调用父类型class的构造函数来帮忙给子对象装缺失的部分属性。
    super: 专门指父类型的构造函数

  4. 结果:
    (1). 子对象中,既可以使用子类型class的原型对象方法,又可以使用父类型class的原型对象方法
    (2). 子对象中,既包含子类型class构造函数中属性,又包含父类型class的构造函数中的属性。
    在这里插入图片描述

  5. 示例: 使用两种class间继承描述飞机大战敌机和降落伞的程序结构
    在这里插入图片描述

  6. 总结: 今后,只要多个class之间包含部分相同的属性结构和方法定义,都要用class继承的方式来避免重复编码

promise

对应小程序视频: 小程序->在线->JSCORE->day06: 3. 回调地狱 callback和promise
链接:https://pan.baidu.com/s/1OZk1dqSxtYb0VV797lQrow 提取码:fwq9

  1. 问题: 在实际开发中,经常需要保证多个异步任务必须顺序执行!

  2. 错误解决: 单纯先后调用多个异步函数,无法保证顺序执行!
    异步: 任务之间互相不等待,互不影响,各自分头执行自己的任务。
    在这里插入图片描述

  3. 不好的解决: 回调函数方式: 2步:
    (1). 前一项任务:
    function 前一项任务(che){//定义一个che变量,准备暂存下一项任务函数
    异步任务…
    在异步任务最后一条执行的语句之后,调用che(),进而相当于执行che变量中保存的下一项任务。
    }0
    (2). 调用时:
    前一项任务(
    function(){ -> 暂时保存到前一项任务的che变量中,暂存,暂不执行
    下一项任务()
    }//没有(),所以暂时不会执行
    //当前一项任务内部,最后一条语句执行完只有,调用了che()
    //才会执行这里function(){ … }中的下一项任务
    )
    在这里插入图片描述

  4. 示例: 使用回调函数保证多个异步任务顺序执行
    在这里插入图片描述

  5. 问题: 回调地狱: 由于使用了多级回调函数,形成了很深的代码嵌套接结构。.
    在这里插入图片描述

  6. 好的解决: ES6的Promise(王牌对王牌,传声筒)
    (1). 如何: 2步
    a. 创建Promise对象(带门的格子间),其中包含要执行的异步任务
    function 前一项任务(){
    return new Promise(
    function(门){
    原异步任务代码
    在原异步任务代码最后执行的一句话之后,调用
    门(); //开门
    }
    )
    }
    b. 调用前一项任务时:
    前一项任务.then(下一项任务) //下一项任务不要加()
    //只是暂时连接,不是立刻执行
    (2)执行过程:
    a. .then会暂时将下一项任务和前一项任务返回的new Promise相连。暂时相连,但暂不执行
    b. 只有当前一项任务的new Promise内部调用了"门()"开门之后,才会自动通知.then,自动调用提前连接的下一项任务。

  7. 前后两任务之间传参
    对应小程序视频: 小程序->在线->JSCORE->day06: 4. promise传参
    链接:https://pan.baidu.com/s/1S06J7zYpgzpK6Ogj5Qz9cA 提取码:y9ff
    (1). 前一项任务中:
    function 前一项任务(){
    return new Promise(
    function(门){
    原异步任务…
    当原异步任务执行的最后一句话之后,开门
    门( 一个变量 )
    }
    )
    }
    (2). 下一项任务:
    function 下一项任务( 一个形参 ){
    … …
    }
    (3). 将来调用时:
    前一项任务().then(后一项任务)
    (4). 原理: 当前一项任务内部调用"门(一个变量)"时,变量的值会顺着.then()自动传给下一项任务。就能被下一项任务的形参变量接住!就可以在下一项任务内部,使用前一项任务传来的变量。

  8. 示例: 使用Promise实现多个异步任务顺序执行,并传参

在这里插入图片描述
总结: this 5种:

  1. obj.fun() this->点前的obj对象
  2. new Fun() this->new正在创建的新对象
  3. 类型名.prototype.共有方法=function(){ … }
    this->将来谁调用这个函数,就指谁
    将来调用这个函数的.前的某个子对象
  4. fun() 和回调函数 和匿名函数自调 this->默认指window
  5. 访问器属性中的this指访问器属性所在的当前对象

总结:
(3). 箭头函数: 今后,几乎所有的function都可用箭头函数简写:
a. 如何: 3句话:
1). 去掉function,在()和{}之间加=>
2). 如果只有一个形参,可省略()
3). 如果函数体只有一句话,可省略{}
如果仅有的一句话还是return,必须省略return
b. 特点: 箭头函数内部的this与外部的this,保持一致。
c. 今后:
1). 如果函数中没有this或者恰好希望函数内this与函数外this保持一致时,可用箭头函数简写!
2). 如果不希望内外this相同时不能使用箭头函数简写。
(4). for of: 今后只要遍历数字下标的索引数组、类数组对象和字符串,都用for of
for in: 今后只要遍历自定义下标名称的对象和关联数组都用for in
在这里插入图片描述
(5). 参数增强:
a. 参数默认值: 定义函数时最后一个形参不确定有没有实参时
function 函数名(形参1, …, 最后形参=默认值){
… …
}
b. 剩余参数: 定义函数时: 只要多个形参不确定,都用剩余参数
function 函数名(其它形参, …数组名){
//…收集除其它形参外多余的实参值保存到指定数组名的数组中
}
c. 打散数组: 今后调用函数时,只要单纯打散数组再传参时
1). 如何: 函数(…数组)
2). …口诀: 定义函数时…表示收集, 调用函数时…表示打散
3). …语法糖:
i. 复制一个数组: var arr2=[…arr1];
ii. 合并多个数组和元素值: var arr3=[…arr1,值,…arr2,值]
iii. 复制一个对象: var obj2={ … obj1 }
iv. 合并多个对象和属性: var obj3={ …obj1, 属性:值, …obj2, 属性:值 }
(6). 解构:
a. 只要想提取出数组中个别元素值,单独使用时,就数组解构:
[变量1, 变量2]=arr;
b. 只要想提取出对象中个别属性值或方法,单独使用时,就对象解构:
var {属性名也是变量名, 属性名也是变量名}=对象
c. 只要多个参数不确定有没有,又要求实参值必须传给指定的形参时,就参数结构:
定义函数时:
function 函数名({
属性名也是形参名=“默认值”,
属性名也是形参名=“默认值”,
… = …
}){
函数体
}
调用函数时:
函数名({
要修改的形参名: 实参值,
… : … ,
})
(7). class extends
a. 定义class:
class 类型名{
constructor(形参列表){
this.属性名=形参;
… = …;
}
共有方法(){
… this.属性 …
}
}
class的底层原理和用法与旧js构造函数用法完全相同!——新瓶装旧酒
b. 继承: 只要两种类型间包含部分相同的属性结构和方法定义,都要额外定义一个父类型集中保存两种类型相同的属性结构和方法定义。然后再让子类型继承父类型
class 子类型 extends 父类型{
constructor(…){
super(…);
this.属性名=形参;
}
子类型共有方法(){

}
}
两步,两个关键字: extends是继承的意思,super()是调用父类型构造函数,请父类型构造函数帮忙添加相同部分的属性的意思。
(8). Promise: 当多个异步任务必须顺序执行时,就可用promise
a. 前一项任务:
function 前一项任务(){
return new Promise(
function(door){
原异步任务;
原异步任务最后一句话之后door()
}
)
}
b. 调用前一项任务时:
前一项任务().then(下一项任务)
c. 如果下一项任务也返回new Promise对象,则可以继续用.then()相连
前一项任务().the(下一项任务).then(之后任务).then(…)…
d. 前后两个任务间传值:
1). 前一项任务内:
door(一个变量);
//只能传一个变量
//如果传多个值,可放在数组或对象中
2). 后一项任务声明时:
function 后一项任务(形参){ … }
//前一项任务:door()中传什么
//后一项任务:形参就接住什么

往届学员作品集: http://www.codeboy.com:9999/pro/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值