正则
1、只要验证字符串格式或查找,屏蔽敏感时都要用正则
(1)最简单的正则:一个敏感词的原文
(2)某一位字符上可能有多种备选字时用:[备选字列表]
(3)如果[ ]中部分字符是连续的,可用[x- x]
a、一位小写字母:[a - z]
b、一位大写字母:[A - Z]
c、一位字母(大小写都行):[ A- Z a-Z ]
d、一位字母或数字都行[ 0-9 A-Z a-z]
e、一位汉字:[\u4e00 - \u9fa5]
(4)预定义字符集:
a、\d 一位数字
b、\w 一位数字、字母或_
c、\s 空格、tab、换行等空字符 ^\s+|\s+S
d、 . 任意字符
2、String家提供的正则相关函数:3件事
(1)查找敏感词:4种情况
1)查找一个固定敏感词出现的位置:
var i = str.indexOf("敏感词”); //如果找不到,返回-1;
2)用正则表达式查找多种敏感词出现的位置:
var i = str.search(/正则/i) .s earch(/([我卧]|wo\s+(槽艹草操|cao/i)
//如果找不到,返回-1
3)查找敏感词的内容:
a、查找第一个敏感词的内容和位置:
var arr = str.match(/正则/i) //如果找 不到返回null
b、查找所有敏感词的内容,不关心位置:
var arr = str.match(/正则/ig)
//arr:[敏感词1,敏感词2,... ]
//如果找不到返回null
4)查找每个每个敏感词的位置和内容:reg.exec
(2)替换敏感词:2种
1)简单替换:
变量 = str.replace(/正则/ig,"新值”)
2)高级替换:
变量 = str.replace(/正则/ig,function(形参){
return 根据本次敏感词动态生成一个新值
})
3)删除敏感词:
变量 = str.replace(/正则/ig,“ ”)
(3)切割字符串:
1)简单切割:
var arr = str.split(“切割符”)
2)复杂切割:
var arr = str.split(/正则/i)
3)打散字符串为字符数组:
var arr = str.split(“”);
知识点一:RegExp对象
(1)创建正则表达式对象
情况一:正则是固定的——var reg = /正则/ig
情况二:正则需要动态生成——var reg = new RegExp("正则",ig)
(2)验证字符串格式
var bool = reg.test(str) //验证字符串格式时返回的是布尔值 函数调用text()
注意:reg必须同时前加^后加$
(3)既查找每个关键词的内容又查找每个关键词的位置:
do{
var arr = reg.exec(str);
if(arr!=null){
获得本次找到的敏感词的内容(arr[0])和位置(arr.index)
}
}while(arr!=null)
补充:js中所有的数组底层本质都是关联数据(下标都为字符串) 1.访问数组中元素值的标注写法:arr["下标"] 2.简写: a.如果下标为自定义字符串名称,可简写为:arr.自定义下标 b.如果下标为数字内容的字符串,可简写为:arr[数字下标] |
知识点二:函数
(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 函数名 = Function(...) 只不过function 函数名(){}是先提前,再翻译 而var 函数名 = function(){}是不提前,原地翻译 |
(2)重载:一件事,可能根据传入不同的参数值,动态执行不同的逻辑时,都用重载
function 一个函数名(不写形参变量){
//arguments对象自动接住所有实参值
if(arguments.length==0){
执行一种逻辑
}else if(arguments.length == 1){
执行另一种逻辑
}else{
执行其它逻辑
}
}
其中arguments是类数组对象:和数组相比:
a.相同点:都有下标,都有length属性,都可以for循环遍历
b.不同点:不是数组类型,无法使用数组家的函数(数组API)
补充:数组家的函数:
(3)匿名函数:
a、所有回调函数优先使用匿名函数——用完释放,节约内存
b、所有js代码都应该保存在匿名函数自调中,禁止使用全局变量,避免全局污染!
(function(){
要执行的js代码;
})();
结果:匿名函数内的都是局部变量,不会产生全局变量
:局部变量随着匿名函数一起释放,不会污染全局!
(4)作用域和作用域链(见图)
a.作用域
1)全局作用域:window ,保存全局变量
优点:可重用
缺点:随处可用,极易被污染
2)函数作用域:保存局部变量
局部变量包括两种:函数中var声明的变量&&形参变量
优点:仅函数内可以使用,不会被污染
缺点:不可重用
3)函数作用域对象原理:
i. 每个函数定义时都自带好友列表,好友列表里2个格子,一个空,一个引用window
ii. 调用函数时临时创建函数作用域对象保存函数局部变量。并将函数作用域对象地址保存在函数好友列表中离自己近的格子当中
iii. 函数执行过程中按就近原则先在自己的函数作用域对象中找局部变量使用。如果找不到,才被迫去全局window中找变量使用。
iv.函数调用后,好友列表中离自己近的格子清空,导致函数作用域对象以及内部的局部变量被释放!——所以局部变量不会被重用
b.作用域链:保存一个函数所有可用的作用域对象的链式结构(好友列表)学名就叫作用域链。
1).作用域链保存着一个函数可用的所有变量
2).作用域链控制着变量的使用顺序。先局部后全局。
面向对象:封装 继承 多态
1、封装:3种:
(1)用{}创建一个对象:
var 对象名 = {
属性名:属性值,
...........:............,
方法名:function(){
.......this . 属性名 .......
}
}
(2)用new Object():只要反复创建多个相同结构的对象都用构造函数。
2步:
//1、定义构造函数
function 类型名(形参1,形参2,...){
this.属性名1 = 形参1;
this.属性名2 = 形参2;
//构造函数内不要再定义对象方法了!
}
//2、用new调用构造函数
var 对象名 = new 类型名(属性值1,属性值2, ...);
其中 new干了4件事:
1)创建一个新的空对象
2)让新对象继承(__proto__)构造函数的原型对象
3)调用构造函数,传入实参,并自动替换构造函数中的this为new创建的新对象。构造函数中,通过强行赋值的方式为新对象添加规定的属性并保存属性值。
4)返回新对象的地址,保存到左边的变量中
2、继承:
今后,只要同一类型所有子对象共用的方法和属性值,都要集中保存在构造函数的原型对象中
构造函数.prototype.属性名/共有方法名 = 属性值/function(){...}
1)自有属性和共有属性:
多态
1、什么是多态?
同一个函数在不同情况下表现出不同的状态。
2、为什么用多态:从父对象继承来的东西,不是都好用的
3、何时使用多态:只要从父对象继承来的东西不好用!就可以自己在对象内部定义一个同名的成员,覆盖父对象中的成员。
4、多态包括:重载(overload)和重写(override)
5、重写:override
(1)什么是重写:
保护对象属性:
(1) 禁止添加属性:Object.preventExtensiond(对象)
原理:自动将对象内部属性extensible=false;从此该对像禁止添加属性
(2)密封:既禁止添加属性,又禁止删除现有属性,但属性值还是可以随便修改:Object.seal(对象)
原理:自动将对象内部属性extensible=false configurable=false;从此该对像禁止添加属性 ,删除现有属性
一般情况下,一个对象保护到密封级别就够了!
(3)冻结:既不能添加删除属性 ,也不能修改属性的值 Object.freeze(对象)
原理:自动将对象内部属性extensible=false configurable=false writable=false;从此该对象禁止添加属性 ,删除现有属性,修改属性的值
何时使用:如果多个模块共用一个对象,应该禁止任何其中一个模块擅自修改共有对象中的属性值,避免牵一发而动全身!
(4)Object.create():基于一个现有对象,创建新的子对象,来继承这个父对象(简单说,没有构造函数,也能创建子对象,继承父对象)
何时使用:没有构造函数时,也想创建子对象
如何使用:a、只创建子对象
var 子对象 = Object.create(父对象 )
创建了一个新的空对象,自动设置了新的空对象__proto__继承父对象
b、既创建子对象,又为子对象添加新的自有属性
var 子对象 = Object.create(父对象,{
//必须采用defineProperties函数同样的格式添加自有属性
自有属性名:{
value:属性值,
writable:true,
enumerable:true,
configurable:false
},
自有属性名:{
value:属性值,
writable:true,
enumerable:true,
configurable:false
}
})
做了三件事:创建了一个新对象 自动设置新的空对象的__proto__继承父对象 为新对象添加自有属性
class
1、什么是:集中存储一个类型的构造函数和原型对象的程序结构
2、为什么:旧的js,明明属于一个类型的构造方法和原型对象方法,是分开写的,不符合封装的要求。
3、何时:今后只要定义一种新类型(包括构造函数和原型对象方法时),都用class来包裹原来的构造函数和原型对象方法
4、如何
1)用class{}包裹之前的构造函数和原型对象方法
2)构造函数名
修改一个函数中的this
1、何时:只要一个函数执行时,其中this不是想要的!都可以随意更换!
2、如何:(1)在调用一个函数时,临时更换一次这个函数中的this为指定的对象,函数调用一次后,this恢复原样!
要调用的函数.call(替换this的对象,实参值列表)
call做了三件事:Call的本意就是调用函数执行的意思,所以函数会执行一次
Call用自己的第一个实参对象,代替函数中所有的this
Call将从自己的第二个实参值向后的所有实参值列表,传给正在调用的函数的所有形参
(2)如果实参值是放在一个数组中给的,不是多个值分着给的。如果要完成同样的替换this的功能,就要换成用apply()实现。因为apply会先打散数组为多个值,再传给函数。
要调用的函数.apply(替换的this对象,数组)
apply做三件事:apply的本意就是使用函数执行的意思,所以函数真的会执行一次
apply用自己的第一个实参对象,代替函数中所有的this
apply先将自己的第二个实参值数组打散成多个实参值,然后将打散后的多个实参值传给正在调用的函数的多个形参。
(3)bind : 基于原函数创建一个一模一样的函数副本,并永久替换函数副本中的this为指定的对象
何时:当一个对象经常调用不属于自己的函数
var 新函数名 = 要调用的函数.bind(替换this的对象)
原理:bind会基于原函数创建一个一模一样的新函数
bind会将新函数副本中的this永久替换成指定的对象
除此之外为了更简洁有时还可以固定第一个参数为固定值!
var 新函数名 = 要调用的函数.bind(替换this的对象,固定的实参值)
注意:回调函数中的this必须用bind替换:bind()不会立刻调用函数,而是返回一个新函数而已,既不会立刻调用又返回新函数,刚好符合回调函数的需要!
为什么不能使用.call()和.apply()换?
.call()和.apply()都是立即执行函数的意思。而回调函数恰恰不希望立刻执行函数。
总结在最后:
(1)函数只要替换一次this为指定对象,则最优选择是.call(),
如果实参值是放在一个数组中而不是单独一个一个给的,则需要.apply()将数组打散再传入。
(2)如果需要反复替换this为指定对象,多次调用函数,选择.bind()最好
(3)如果要替换this的函数是回调函数,则必须使用bind(),因为.call()和.apply()都是立即调用函数。
回调函数:自己定义的函数,自己不调用,给别的函数调用
何时:当函数内部缺少一段逻辑,需要动态补充时(可以理解为把一个函数(回调函数)当作另外一个函数(主函数)的参数使用)
数组家的新函数
1、判断 :
(1)判断数组中是否所有元素都符合要求
var bool= arr.every( //every内部自带for循环,遍历数组中的每个元素
function(elem, i, arr){ //每遍历一个元素,就自动调用一次回调函数
//elem 会自动获得当前遍历的数组元素
//i 会自动获得当前遍历的数组元素的下标位置
//arr 会自动获得当前调用every()时.前的数组对象arr
return 判断条件;
}
//回调函数用提前写好的判断条件,判断数组中当前元素是否符合要求,返回判断结果为布尔值(true/false)
//如果本次调用回调函数,返回false,则会退出every()函数的执行,不在继续遍历。直接返回结果——false,表示数组中不是所有元素都符合要求。
//如果本次调用回调函数,返回true,则继续执行循环遍历下一个元素,直到所有元素都遍历完毕,都返回true,整个every(),才能返回true,说明整个数组所有元素都符合条件要求
)
(2)判断数组中是否包含符合要求的元素
var bool= arr.some( //every内部自带for循环,遍历数组中的每个元素
function(elem, i, arr){ //每遍历一个元素,就自动调用一次回调函数
//elem 会自动获得当前遍历的数组元素
//i 会自动获得当前遍历的数组元素的下标位置
//arr 会自动获得当前调用every()时.前的数组对象arr
return 判断条件;
}
//回调函数用提前写好的判断条件,判断数组中当前元素是否符合要求,返回判断结果为布尔值(true/false)
//如果本次调用回调函数,返回true,则会退出some()函数的执行,不在继续遍历。直接返回结果——true,表示数组中包含符合要求的元素。
//如果本次调用回调函数,返回false,则继续执行循环遍历下一个元素,直到所有元素都遍历完毕,都返回false,整个some),才能返回false,说明整个数组所有元素不包含 符合要求的元素
)
补充:
按值传递:两个变量间赋值时,其实都是将原变量中的值复制一个副本给对方。
(1)如果传递的是原始类型的值:number、string、bool、null、undefined
将原始值复制一个副本给对方,修改新变量的值,不影响原变量
(2)如果传递的是引用类型的值:数组,日期,自定义对象
只是将地址值复制给新变量。形成两个变量用相同的地址指向同一个对象,任何一方修改对象,另一方都会受影响。
遍历数组
(1)forEach VS for
1)for可以遍历一切数字下标的东西;
比如:索引数组,类数组对象(arguments),字符串
2)forEach只能遍历索引数组
其他类数组对象和字符串,因为都不是数组家孩子!所以都无权使用数组家forEach
(2)map:遍历出原数组中每个元素,修改后,放入新数组中返回
1)何时:只要希望原数组保持不变,而希望根据原数组中的每个元素,一对一修改出一个新数组返回。
var 新数组 = arr.map(
//1、自带创建一个新空数组
//2、自带for循环,遍历数组中的每个元素
//3、每遍历一个元素,就自动调用一次回调函数
function(elem,i,arr){
//elem自动获得当前正在遍历的元素内容
//i自动获得当前正在遍历到的位置
//arr 自动获得当前正在调用map()的.前的数组对象
//因为加工后的新元素值要放入新数组中,所以回调函数需要return新加工后的新元素值给map,由map放入新数组中。
return 加工后的新元素值;
}//map收到回调函数返回的每个加工后的新元素值后,会自动放入新数组中相同位置
//map会返回新数组对象
)
原理:
a、filter第一件事儿是先创建一个新的空数组
b、filter内部也自带for循环,自动遍历原数组中的每个元素
c、每遍历一个元素,就自动调用一次回调函数,每次调用回调函数都自动传入三个值
elem:当前正在遍历的数组元素值
i:当前正在遍历的数组元素的下标
arr:当前调用map函数(.前的)数组对象本身
d、回调函数内部对当前遍历到的元素加工后,返回新元素给map()函数
e、map()函数负责将回调函数返回的新元素值,放入新数组中相同的位置
f、当遍历结束,则map()返回新数组。原数组内容保持不变。
此处小总结:
1)如果单纯遍历原数组,不产生新数组时,就用forEach
2)希望保护原数组,而产生新数组时,就用map()
过滤和汇总:
(1)过滤:复制出数组中符合条件的元素,组成新的子数组返回。原数组保持不变。
var 新数组 = arr.filter(function(elem,i,arr){
//因为要根据回调函数的判断结果来决定是否将当前元素放回新数组中返回,所以需要返回一个判断条件
return 判断条件;
})
原理:
a、filter第一件事儿是先创建一个新的空数组
b、filter内部也自带for循环,自动遍历原数组中的每个元素
c、每遍历一个元素,就自动调用一次回调函数,每次调用回调函数都自动传入三个值
elem:当前正在遍历的数组元素值
i:当前正在遍历的数组元素的下标
arr:当前调用filter函数(.前的)数组对象本身
d、回调函数内部对当前遍历到的元素进行判断后后,返回判断结果
e、filter()函数根据回调函数返回的判断结果来决定是否将当前元素追加到新的空数组当中,只有那些经过回调函数判断返回判断结果为true的元素才有资格追加到新数组当中
f、当遍历结束,则filter()返回新数组。原数组内容保持不变。
(2)汇总:对数组中的元素进行统计,最后得出一个结果
仅以求和为例:
var sum = arr.reduce(
//1、reduce先定义好变量保存起始值
//2、reduce自带for循环,遍历数组中的每个元素
//3、每遍历一个元素,也自动调用一次回调函数
function(prev,elem,i,arr){
//elem:当前正在遍历的数组元素值
//i:当前正在遍历的数组元素的下标
//arr:当前调用filter函数(.前的)数组对象本身
return prev + elem;
},
起始值
)
原理:
a、reduce先用一个保存临时汇总值的变量暂时保存起始值
b、reduce比那里数组中的每一个元素,每遍历一个元素就调用一次回调函数
c、每次调用回调函数时:
将保存临时汇总至的变量交给回调函数的第一个形参prev
将当前遍历到的当前元素值交给回调函数的第二个形参elem
将回调函数中当前临时汇总值与当前元素值求和,再返回 保存临时汇总值的变量当中,为下次汇总做准备
循环结束后,保存临时汇总值的变量中,就会获得整个数组所有元素值的和。
最后reduce返回这个和。
ES6
1、模板字符串:只要拼接字符串,都用模板字符串替换+
整个字符串包裹在一对反引号`...`中
反引号``中支持换行、“”、‘’均可使用
反引号中需要动态生成的内容必须放在${ }里
${}里:可放有返回值的合法的变量或js表达式
不能放程序结构(分支或者循环)以及没有返回值的js表达式
2、let:今后,声明变量都用let替换var
阻止声明提前
让代码块(分支和循环{}也变成块级作用域,{}块内的变量出了{}无法使用,不会影响外部)
在同一作用域内禁止重复说明
禁提前使用
在全局声明也不保存在window
let底层相当于匿名函数自调
箭头函数:
1、什么是:绝大部分function的简写
2、何时使用:今后几乎所有function都可用箭头函数代替(function太长了,总写麻烦)
所以,今后框架中就不应该出现function。
3、如何使用: (1)去掉function,在()和{}之间加上=>
(2)如果形参列表只有一个形参变量,则可以省略()
(3)如果函数体只有一句话,可省略{}
如果函数体仅有一句话,还带有return,则必须省略return!
4、箭头函数特性:函数内部this与函数外部this相通
(1)好的地方:可以不用bind,仅用箭头函数,就可轻松实现内外this相通
(2)不好的地方:对象的方法不能用箭头函数!对象中的方法本来就要求内部的this与外部的this不相通!
解决:ES6中规定,所有对象{}中的方法,都不用加:function(),但是这种简写不会影响this,所以不会造成出错误。
此处小总结:
(1)只要不涉及this,或者刚好希望函数内外this相同的函数,都可用箭头函数简写
(2)如果反而不希望内外this相同的函数,不能用箭头函数简写。
for of :单纯用来简化for循环
何时使用:只要不需要关心遍历的位置,不需要修改遍历的顺序和步调的大部分普通for循环,都可用for of 简写。
局限:(1)无法在遍历时获得遍历的位置
(2)无法修改遍历的顺序步调(不能倒序遍历一个数组,不能每隔XX个元素遍历一次)
for(var 变量 of 数组/类数组对象/字符串){
//of会依次取出数组中每隔元素的值,保存到of前面的变量
}
for of VS for in VS forEach
(1)所有数字下标的索引数组,类数组对象、字符串都可用for of遍历,其中,只有索引数组才能用forEach()
且for of获得的是元素值,而不是元素的下标
(2)所有自定义下标名称的关联数组,对象都用for in遍历,强烈建议不要用for in 遍历索引数组!因为in的意思不仅仅是遍历当前对象内的下标,还会遍历父对象中可用的所有属性名。
参数增强
1、默认值(default)
(1)什么是:即使调用函数时,没有为某个形参变量指定实参值,这个形参变量也有备份的默认值可用
(2)何时:今后只要希望一个形参变量在调用函数时,即使没有传入实参值,也有备用的默认值使用时,就用默认值语法。
function fun (形参值 = 默认值){
}
结果:a、如果将来调用函数时,给形参1提供了实参值,则使用提供的实参值
b、如果将来调用函数时,没有给形参1提供实参值(或者提供undefined),则使用定义函数时预设的默认值作为形参变量的值。
旧js 中兼容写法:
function (形参1){
形参1 = 形参1 || 默认值
//如果形参1是有意义的值(不是undefined),则使用形参1的值。复习第一阶段的短路逻辑和隐式转换
}
默认值只能解决最后一个形参不确定有没有的情况!
如果多个形参都不确定有没有,应该用后边学的参数解构来解决!
2、剩余参数(rest)
(1)什么是:专门代替arguments的一种新的获得不确定个数实参值的新方法
(2)为什么:arguments的缺点:a、单词太长,且没有意义!还不能自定义
b、不是数组类型,无法使用数组家好的函数
c、arguments只能所有实参值照单全收,不能有选择的收取一部分实参值!
d、ES6中的箭头函数,禁止使用arguments了。
(3)何时使用:只要 想要使用argguments时,都可以换成剩余参数语法!
(4)如何:定义函数时:
1)从头到尾获得所有实参值:
function fun(...数组名){
.......
}
其中:...的意思是“收集”,把传给函数的所有实参值都收集到...后的数组里保存!
2)剩余参数可以收集部分实参值
function(形参1,形参2,...数组名 ){
}
结果:...数组名收集的是除了前两个形参变量对应的实参值以外的剩余参数值
(5)好处:a、数组名可以自定义;
b、是纯正的数组!可以使用数组家所有好的函数!
c、可以有选择的获得部分实参值,而不必非要照单全收。
3、打散(spread)数组和对象
(1)什么是:将一个数组打散为多个元素值,依次传给函数的多个形参变量
(2)何时:只要需要多个值,但是多个值是放在数组中给的,都要先 打散数组,再使用多个值。
(3)如何:调用函数时
函数名(...数组名)
其中...是打散的意思将数组打散为多个元素。
(4)结果:先将数组打散为多个值,再传给函数作为实参值
(5)其他固定套路(语法糖):
a、复制一个数组
var arr2 = arr.slice();
var arr2 = [...arr]; //先打散数组,将原数组中的每个值放入新创建的数组中
b、合并数组
var arr3 = [].concat(arr1,arr2);
var arr3 = [...arr1,...arr2]; //先将两个数组打散,再将所有元素放入新创建的数组
(6)...打散对象
a、浅克隆对象:var obj2 = {...obj1}; //先打散obj1对象,然后将打散后的所有属性,放入新对象中!
b、合并两个对象:
1)var obj3 = Object.assign({},obj1,obj2);//先将obj1和obj2打散后,所有的属性都放入第一个参数空对象返回
2)var obj3 = {...obj1,...obj2};//先将obj1和obj2打散后,所有的属性都放入新创建的空对象返回
解构:
(1)什么是:将一个大的对象或数组中的个别成员提取出来单独使用
(2) 为什么:在面向对象编程中,往往要先定义好对象的所有属性和方法,然后再按需调用对象中的成员属性和方法,每次调用总要带着对象名前缀,太麻烦!0
(3)何时使用:只要在一个大的对象或者数组中,只想要其中的个别成员时,都要先将其解构出来,再脱离开对象单独使用该成员。
(4)如何:1)数组解构
//先将等号左边等着接元素的变量装扮成数组的样子,再用等号赋值
var[变量1,变量2] = 数组;
//结果:下标对下标,自动赋值
变量1= 数组[0], 变量2 =数组[1].......
2)对象解构:从对象中提取出个别成员(属性和方法),单独使用
//先将等号左边等着接属性值的变量装扮成等于右边对象一模一样的样子(要带属性名),再用等号赋值
var[属性名1:变量1,属性名2:变量2] = 对象;
//结果:属性名对下属性名,自动赋值
变量1= 对象.属性名1的属性值, 变量2 = 对象.属性名2的属性值......
3)参数解构 :将所有的形参和实参都包裹在对象结构中,再传参!
定义函数时:
function 函数名({
属性名1:形参1,
属性名2:形参2,
... : ...
}){
......
}
调用函数时:
函数名({
属性名1:形参1,
属性名2:形参2,
... : ...
})
强调:一旦定义函数时采用了对象解构的形式,则调用函数时必须传入一个对象解构。
虽然定义函数时,属性名和形参变量可以合为一个名字,但是调用时,属性名和实参值必须都要写完整!
如果属性名和形参变量合为一个,如果给形参变量赋默认值,就可用ES6语法格式。
总结:this 6种
1、obj.fun() this->点前的obj对象 ,比如lilei.insr() this->lilei
2、new Fun() this->new正在创建的新对象
3、类型名.prototype.共有方法 = function(){...}
this - >将来谁调用这个函数,就指谁
将来调用这个函数的.前的某个子对象
4、fun()和 回调函数 和 匿名函数自调 this->window
5、访问器属性中的this->当前访问器属性所在的对象
6、在DOM的事件处理函数内的this->当前正在触发事件的DOM元素对象
Promise
、