ES6入门笔记------1-9各种扩展

1、let和const

let使用注意:作用域只在当前代码块,变量不会提升(暂时性死区),相同作用域不能重复声明,for循环体现父子作用域

const使用注意:作用域只在当前代码块,变量不会提升(暂时性死区),相同作用域不能重复声明,声明即需赋值不能改(对象属性值可修改)

 

2.块级作用域:

<1>外层作用域无法读取内层,内层可以定义外层同名作用域

<2>ES5函数只在顶层作用域和函数作用域内申明

      ES6浏览器,块级作用域允许申明(只有在使用大括号的),申明类似var,会提升(行为差异大,尽量避免或者用函数表达式)

<3>do表达式: let x=do{ return 'wtf?0 0' }  可以返回块级作用域的返回值(提案)

 

3.解构赋值

<1>等号右边具有 Iterator 接口,就可以一一对应赋值(Iterator 接口:数组、某些类似数组的对象、Set和Map结构)

<2>等号左边允许设置默认值:let [y=1]=[]   (===undefine  才生效)

<3>默认值如果是表达式,惰性求值,即只有需要生效的时候才求值

<4>对象解构,变量和属性名对应,不用一一对应,否则就需要

<5>左边为对象,右边字符串,转成类似数组对象,数字和布尔值,转成对象,null和undefined无法转,报错

<6>函数解构,默认值是参数对象的默认值,move({x,y}={x:0,y=0}) ,当move({}),x,y都为undefined;当move(),默认值生效

<7>三种不能使用()的情况:变量声明语句:let [(a)]=[1];函数参数:function f( [(z)] ){ return z;} ;赋值语句的模式:( [a] )=[5]

<8>赋值语句的非模式:[ (a) ]=[3];

 

4.字符串扩展(字符在JS以UTF-16格式储存,2字节/字符)

<1>字符的 Unicode 表示法:’\u{lF680}’===’\uD83D\uDE80 ’  (即将码点放进大括号就与四字节UTF-16等价)

<2>charAt(index)以单字符字符串的形式返回给定位置的那个字符。
      chatCodeAt(index)返回给定位置的那个字符的字符编码。

       codePointAt (index) 能处理4字节的字符,返回的是给定位置的字符的十进制码点(二字节的字符,返回同chatCodeAt)   ----ES6 --定义在字符串实例对象上

<3>String fromCharCode()不能识别 32 位的 UTF 16 字符( Unicode 编号大于 OxFFFF )--ES5

       String fromCodePoint()能,多个参数的时候会被合并成一个字符串返回---ES6 --定义在string对象上

<4>normalize() 统一不同表示的字符的形式:’ \ u01Dl ’ . normalize() === ’ \ u004F \ u030C ’. normalize () 

       有四个参数:NFC,NFD,NFKC,NFKD(需要则查)

<5>确定一个字符串是否包含在另一个字符串:indexOf

      新增:都支持第二个参数,便是开始搜索的位置

                 includes():返回Boolean;

                 startsWith():返回Boolean,是否在源字符串的头部,第n到结束

                 endsWith():返回Boolean,是否在源字符串的尾部,前n个字符是否存在指定字符串

<6>repeat(num),将字符重复num次返回新字符串,取num的整,为负数或者Infinity报错。num为字符串先转化数字

<7>padStart(),padEnd():头尾补全,参数一指定字符串最小长度;参数二用来补全的字符串(‘’则用空格补全 )

      用途:数值补位:100000;提示字符串格式:‘12’.padStart(10,’YYYY-MM- DD ’ ) // ” YYYY- MM- 12 ” 

<8>模板字符串:‘html代码’ ,中间如果有变量等:${变量或者表达式或者函数调用};中间如果有反引号(‘), \  转义。

      中间的空格和换行将被保留。模板中的变量可以嵌套另一个模板

<9>标签模板:函数后面跟字符串模板:alert '123'  === alert(123)

      可以过滤HTML字符串,防止恶意内容(通过获取变量转化),同时标签模板中的js语言中可以嵌入其他语言(还可以再深入了解)

<10>String.raw:变量替换,并对反斜线进行转义(如果已转就不处理),作为正常函数(不理解???)

 

5.正则扩展

<1>u修饰符,增加之后可以处理4字节的UTF-16编码:/<\uD83D/u . test (’\uD83D\uDC2A ’) I I false

      大括号表示 Unicode 字符的表示法,必须加上u,否则会被解读为量词:

       / \ u{61}/.test (’ a ’)                //false

        / \ u{61}/u.test (’ a ’)                //true

<2>y 修饰符:全局匹配,默认匹配的值前面有个隐藏的^(即从头匹配),遵循lastIndex属性。

<3> 正则对象多了sticky属性,表示是否设置了y修饰符,值为Boolean;

       新增flags属性,会返回正则的修饰符(source是ES5返回正则的正文)

<4> 先行断言(支持,eg:x在y前才匹配)和后行断言(反之)

<5>了解:\p{ ... }和\P { ... },允许正则表达式匹配符合 Unicode 某种属性的所有
字符,比如指定匹配希腊字符什么的,需要再深入了解

<6>具名组匹配:

 /(\d{4})-(\d{2})-(\d{2})/   ===》/ (?\d{4})-(?\d{2} )-(?\d{2} ) / ; 

?<组名>(匹配)。   然后拿的时候arr.groups.组名         arr为匹配结果

 

6.数值扩展

<1>ES6 提供 进制和八进制数值的新写法,分别用前缀 0b(0B)和 0o(0O)表示。要转成十进制,用Number(str)

<2>全局的isFinite(),isNaN()  和  Number.isNaN,Number.isFinite的区别:

      前者先将非数值转为数值再进行判断,后者只对数值有效,非数值一律返回false

<3>全局方法parseInt ()和 parseFloat ()移植到了 Number 对象上面

<4>Nurnber.islnteger() 用来判断 个值是否为整数。JS内。3和3.0为同一个值。

<5>Number.EPSILON 的实质是 个可以接受的误差范围,浮点数运算是不精确的。

<6>js的极限值2的53次方,超出值仍未2的53次方

ES6 引入了 Number.MAX_SAFE_INTEGER Number.MIN_SAFE_INTEGER 两个常
用来表示这个范围的上下限,Number.isSafeInteger ()来判断是否落在这个范围内
Number.MAX SAFE INTEGER === Math.pow(2, 53) - 1 

<7>Math对象上新增函数(非数转数,转不了NaN)

      Math.trunc():  去除小数部分;

      Math.sign(): 判断是否未正数(+1),负数(-1),0(0,-0);

      Math.cbrt():算立方根

      Math.clz32(): 返回一个数的32位无符号整数形式有多少个前导0  ------(再说)

      Math.imul(): 返回两个数以 32 位带符号整数形式相乘的结果,返回的也是 32的带符号整数。 ------(再说)

      Math.fround(): 返回回最接近这个小数的单精度浮点数。 ------(再说)

      Math.hypot(): 返回所有参数的平方和的平方根。

      Math.expml (x)返回 (e^{x} -1) ,即 (Math.exp(x) -1) 。

      Math.log1p(x)返回 ln(1+x) ,即 Math.log(1+x) 。

      Math.log10(x)返回以 10 为底的 x的对数。如果x 小于 0,则返回 NaN

      Math.log2(x)返回以 2 为底的 x的对数。如果x 小于 0,则返回 NaN

      新增(**):a **=2 即位a的平方,3则为3次方

<7>提案:Integer数据类型(JS 所有数字都保存成 64 位浮点数,所以大于一定范围无法精确表示,不合适进行科学和金融的精确计算),只用来表示整数,没有位数限制,为了和Number类型区分,数据后面都必须加n:

       例子: 1n+2n===3n         0b1101n   //二进制   0o777n  //八进制   0xFFn  //十六进制

       运算: + - *  **四个同Number 。除法的话只返回整数部分。不能同Number类型数据混合运算

 

7.函数扩展

<1>函数参数设置默认值,应该是放在尾部,如果不是放在尾部,则说明这个参数是必传的,如果不传或者null报错,undefined可以,因为会触发默认值。

<2>函数指定默认值后,(fun(){}).length 返回的是没有默认值的参数个数,即失真。如果设置默认参数的不是尾参数,那么后面的参数也不计入length。

<3>函数设置参数默认值,相关作用域

let x=1;
function wwww (x, y=x){ 
    let x=3; 
    console.log(y)
}
www2(2);   //2

这里参数y=x,x指向的是第一个参数。如果没有参数x,x就没有定义,y=x的时候,x指向外面的那个x=1,如果外面的x不存在则会报错

<4>rest参数(...参数名):参数名是一个数组,它把所有参数放进该数组

<5>ES6规定函数参数只要使用了默认值,解构赋值或者扩展运算符,那么函数内部不能使用‘use strict’,否则报错。原因再看

<6>函数的name属性:fun.name返回该函数的函数名,如果匿名函数赋值给一个变量,ES5返回空字符串,ES6返回该变量名。

     如果具名函数赋值给变量,还是返回函数名。

     构造函数返回的函数实例,name的值为anonymous

     bind返回的函数,返回的函数名前面 + bound。

<7>箭头函数的注意事项

       1.不能使用arguments参数,可以使用rest参数代替

       2.不能使用yield命令,因为不能作用于Generator函数

       3.箭头函数无this,所以call,bind,apply这些方法无法使用去改变this

<8>尾部调用:函数的最后一步是调用另一个函数,即return fun(x),如果不是return,则还有一步return undefined

      目的是,尾调用优化,函数调用会形成一个调用帧,如果尾调用不会用到外层函数的变量,这样就会只保留这个内部函数的调用帧,节省内存

     重要运用,尾递归(ES6严格模式,其他可用循环代替,用一个状态)

 

8.数组扩展

<1>扩展运算符:...[数组],类似于rest参数,把数组变成以逗号分隔的参数序列,不仅应用在函数参数,还可以应用在其他地方

      运用:1.扩展符与解构结合:const [first, ...rest] = [1 , 2 , 3 , 4 , 5];    //1,[2,3,4,5]

                 注意:...rest依旧只能放在最后一位,否则报错。

                 2.32为Unicode字符会被js识别为2个字符,用扩展(...字符串)则可以正确识别长度

                 3.具有Iterator接口的对象,可以使用扩展运算符

<2>Array.from()方法:可以将类数组对象(eg:DOM操作返回的NodeList集合,arguments对象,,本质特征是有length属性)和可遍历对象(Set和Map数据结构) 转为真正的数组;

      Array.from(arrayLike , x => x*x)    第二个参数作用类似数组map方法,会把每个元素进行处理,如果map方法中用到this,则还可以传入第三个参数用来绑定this

<3>Array.of()方法:将一组值转成数组

      因为Array(3) //[,,,] 而不是[3]         所以可以用Array.of()来代替

<4>copyWithin(开始替换的位置,读取的开始位置,读取结束位置),第一个参数必传,如果有负,则倒着数

      eg:[ 1, 2 , 3 , 4, 5 ]. copyWithin( 0 , 3 , 4)   //  [ 4, 2 , 3 , 4, 5 ]

<5>find和findIndex()用于数组中寻找第一个符合的元素,前者找到返回值,找不到undefined;后者返回index/-1

<6>fill()用来填充一个数组: [ 数组 ].fill(填充的值,填充初始位置,填充结束位置) 

    eg:  [ ’ a ’,’b ’,’ c ’ ]. fill (7)    //[ 7,7,7]

<7>entries()、 keys()和 values()遍历数组,分别是对键值对,键名,键值的遍历

<8>includes():数组中是否包含给定值,返回Boolean,而indexOf()找的是index,而且判断的时候使用===,会导致对NaN的误判;Set和Map结构有个has方法,前者用来找值,后者用来找键名

<9>数组中的空位,在ES5,ES6,不同方法的处理(需要再查),可能会被视为undefined,也有会被忽略,所以进来避免出现空位

 

9.对象扩展

<1>简洁表达式:ES6允许在对象中只写属性名,属性值等于属性名所代表的变量,写入方法也一样:

      {  funName () { console.log ('略略略') }  }   // { method: fun(){} }

      如果写入的方法值是一个Generator函数,则要在名字前加上星号

<2>属性名表达式:在定义对象的时候,可以用表达式作为对象的属性名(把表达式放在[ ]内),eg:

let test='emmm';
let obj={
    [test]:true,
    ['a'+'bc']:123
}
obj[test]  //true
obj['emmm']  //true
obj['abc']  //123

          注意:属性名表达式合简洁表达式不能同时使用,否则会报错;属性名表达式如果是一个对象,默认转为字符床[ object , Object ]

<3>方法Object.is()传入要比较的两个值,返回Boolean,与===的区别在于,该方法+0!== -0 以及NaN等于自身

<4>Object.assign() 方法第一个参数是目标对象,后面可传入n个源对象,它会将源对象所有可枚举的属性复制到目标对象上,同名则后覆盖前。

       如果参数不是对象,则先转为对象,如果无法转为对象,则会被跳过。

       注意:1.该方法是浅复制,即复制对象的值如果是个对象,则复制的是这个对象的引用,键名同名会被替换,小心

                  2.如果用来处理数组,会把数组视为对象来处理

        常见用途:1.为对象添加属性;  2.为对象添加方法;  3.克隆对象(只能克隆本身的值) 4.合并对象  5.设置默认值

<5>属性的可枚举性:对象每个属性都有一个Descriptor,用来控制该属性的行为,用Object.getOwnPropertyDescriptor(对象名,'属性名'),获取到:{ value:xxx,  writable:true,   enumerable:true(可枚举性),  configurable:true }

       for...in, Object.keys(),   JSON.stringify(), Object.assign() 会忽略enumerable为false的属性

<6>5种属性的遍历的方法

       1. for...in:遍历循环对象自身和继承的可枚举属性,不含Symbol属性

       2. Object.keys(obj):返回一个数组,包括自身所有可枚举属性名

       3. Object.getOwnPropertyName(obj):返回一个数组,包含对象自身所有属性,不含Symbol属性,但包含不可枚举的属性

       4. Object.getOwnPropertySymbols(obj):返回一个数组,包含对象自身所有的Symbol属性

       5. Reflect.ownKeys(obj):返回一个数组,包含对象自身的所有属性,不管是Symbok还是字符串,不管是否可枚举

       遍历原则:a:属性名为数值的,按数字排序 ;b:属性名为字符串的,按生成时间排序;c:属性名为Symbol值的属性,按生成时间排序

<6>原型属性_proto_:无论从语义角度和兼容性角度,都不要直接使用,而是用

      Object.setPrototypeOf()  写,设置对象的prototype属性,返回参数对象本身

      Object.getPrototypeOf()  读

      Object.create()  生成

   读和写的第一个参数为对象,如果不是对象将转为对象,返回的是第一个参数本身;写的第二个参数是要传的内容

<7>对象的扩展运算符(...)

      解构赋值(不会复制原型对象的属性):let {x,...y}={ x:1, y:2, a:3}    y// { y:2, a:3}

<8>Object.getOwnPropertyDescriptors()  ES6:获取对象所有自身的描述。返回的是一个对象,键名同参数对象键名,值为描述。ES5有Object.getOwnPropertyDescriptor()------不带s,是对象的单个某个属性描述,第一个参数也是一个对象,第二个参数为键名。引入的原因是Object.assign()无法争取复制get和set属性(因为该方法总是复制一个属性的值,而不会复制它背后的取值方法或赋值方法)。所以正确复制如下:

const combineObj= (target, source) => Object.defineProperties(
    target,
    Object.getOwnPropertyDescriptors(source) 

<9>一个提案:Null传导运算符 

     当获取message.body.user.firstName的值的时候,如果body不存在则会报错。所以不用层层判断,提案简写:

     message?. body?. user?.firstName  只要其中一个返回null或者undefined就不再往下,返回undefined

你可能感兴趣的:(js书,日常学习)