ES6中的变量 字符串 函数对象
变量 字符串 函数 对象
变量:
let 声明变量:
- 解决全局污染问题,let 声明的变量不会挂载到全局变量。
- let 声明的变量,不允许在一个作用域范围内(全局作用域,函数作用域,块级作用域)重复声明 。
- 块级作用域:{},在块级作用域中定义的变量,在外部无法访问。
- let 变量不会变量提升,不能在定义之前使用该变量。
- 在循环中,用 let 声明的变量会进行特殊处理,每次进入循环体,都会开启一个新的作用域,并且将循环变- 量绑定到该作用域(每次循环使用的是一个全新的变量)。
- 用 let 声明的循环变量在循环结束时会自动销毁。
const 声明常量:
- const 和 let 完全相同,仅在于 const 声明的变量,必须在变量声明时赋值,而且不可以重新赋值。
- 多使用 const 避免犯错。
- const 声明一个对象时,对象里面的属性是可以更改的,仅仅是对象的名不能重新赋值。
- 在 for 循环中循环变量不能使用 const 常量,在 for in 循环中可以使用。
字符串:
字符串 API(以下全为实例方法):
- includes(子字符串,开始查找的索引值(可省略,默认从 0 开始)):判断字符串是否包含指定的子字符串。
- startWith(子字符串,开始查找的索引值(可省略,默认从 0 开始)):是否以指定字符串开头。
- endWith(子字符串,字符串的长度(可省略,默认为字符串 长度)):是否以指定字符串结尾。
- repeat(count):将字符串重复指定的次数,重新返回一个新的字符串。
模板字符串:
写在 `` 里面,
要拼接字符串,将要拼接的字符串加在${}里。
1 | var level1 = "谢永强"; |
在模板字符串前面加上标记 : String.raw ,可以将模板字符串里面的特殊字符直接输出。
1 | var text1 = String.raw`谢永强\t真帅!`; |
函数:
参数默认值:
参数默认值,在定义函数时直接给形参赋值,如果调用函数时不传递参数(或传递 undefined),则使用默认值。
在严格模式下(“use strict”)下形参和 arguments 是脱离的(不再满足一一映射关系),只要给函数加上了参数默认值,该函数会自动变成严格模式下的规则(形参和 arguments 是脱离的)
1 | function test(a, b = 4) { |
剩余参数:
函数名.length :可得到函数形参的个数
解决参数数量不确定情况下的问题。
实现方法:在函数是形参中加上 (…数组名)就可以了,用一个数组收集剩下的所有参数。
一个函数只能有一个剩余参数。
一个函数如果有剩余参数,剩余参数必须是最后一个参数。
1 | function sum(a, b, ...args) { |
展开运算符:
作用:将数组的每一项分别提取出来。
语法:在要展开的数组和对象前面加上(…数组名 / …对象名)。
1 | let arr = [1, 2, 3, 4, 5, 6, 7, 8]; |
new.target :可用来判断函数是否用 new 来调用函数。
this 指向:
- 通过对象调用函数,this 指向对象
- 直接调用函数,this 指向全局对象
- 如果通过 new 调用函数,this 指向新创建的对象
- 如果通过 apply、call、bind 等调用函数,this 指向指定的数据
- 如果是 dom 对象,this 指向事件源
箭头函数:
使用语法
箭头函数是一个函数表达式,理论上,任何使用函数表达式的场景都可以使用箭头函数
1 | // 完整语法: |
注意细节
- 箭头函数中,不存在 this、arguments、new.target,如果使用了,则使用的是函数外层的对应的 this、arguments、new.target
- 箭头函数没有原型
- 箭头函数不能作用构造函数使用
应用场景
临时性使用的函数,并不会可以调用它,比如:
- 事件处理函数
- 异步处理函数
- 其他临时性的函数
- 为了绑定外层 this 的函数
- 在不影响其他代码的情况下,保持代码的简洁,最常见的,数组方法中的回调函数
对象:
变量字面量语法:
成员速写:
如果对象字面量初始化时,成员的名称来自于一个变量,并且和变量的名称相同,则可以进行简写,可将 变量名:变量名 简写成 变量名
方法速写:
可以将:function 省略。
1 | function test(name, age, sex) { |
计算属性名:
有的时候,初始化对象时,某些属性名可能来自于某个表达式的值,在 ES6,可以使用中括号来表示该属性名是通过计算得到的。
1 | const prop1 = "name"; |
Object 的新增 API:
- Object.is:
判断两个对象是否相等,基本和 === 是一致的,除了 NaN 和 NaN 相等 、 +0 和-0 不相等
1 | console.log(Object.is(NaN, NaN), NaN === NaN); |
- Object.assign:
用于混合对象(可以用展开运算符实现);
缺陷:会更改原来的第一个对象,解决方案:第一个参数传递一个空对象 - Object.getOwnPropertyNames:
Object.getOwnPropertyNames 方法之前就存在,只不过,官方没有明确要求,对属性的顺序如何排序,如何排序,完全由浏览器厂商决定。
ES6 规定了该方法返回的数组的排序方式如下:
先排数字,并按照升序排序
再排其他,按照书写顺序排序 - Object.setPrototypeOf
该函数用于设置某个对象的隐式原型
比如:Object.setPrototypeOf(obj1, obj2), 相当于: obj1.__proto__ = obj2
类:
传统的构造函数的问题
- 属性和原型方法定义分离,降低了可读性
- 原型成员可以被枚举
- 默认情况下,构造函数仍然可以被当作普通函数使用
类的特点
- 类声明不会被提升,与 let 和 const 一样,存在暂时性死区
- 类中的所有代码均在严格模式下执行
- 类的所有方法都是不可枚举的
- 类的所有方法都无法被当作构造函数使用
- 类的构造器必须使用 new 来调用
类的语法:
1 | class 类名{ |
1 | class Animal { |
类里面属性的获取和更改:
可达到像普通对象一样直接获取,设置属性又不保证安全。
获取:
可定义一个方法
1 | get 属性名(){ |
更改:
定义一个方法
1 | set 属性名(参数){ |
1 | class Test { |
静态成员:
直接定义在类上的属性或方法,在类中用关键字 static 定义,不用创建实例对象就可以访问的属性,创建的实例对象不可以访问这个属性。
1 | class Test { |
字段初始化器:
可以将一些有固定值的属性直接写在构造函数外面。
1 | class Test { |
类的继承
如果两个类 A 和 B,如果可以描述为:B 是 A,则,A 和 B 形成继承关系则:
- B 继承自 A
- A 派生 B
- B 是 A 的子类
- A 是 B 的父类
如果 A 是 B 的父类,则 B 会自动拥有 A 中的所有实例成员。
继承的关键字:
extends:继承,用于类的定义
super
- 直接当作函数调用,表示父类构造函数
- 如果当作对象使用,则表示父类的原型
注意:
- ES6 要求,如果定义了 constructor,并且该类是子类,则必须在 constructor 的第一行手动调用父类的构造函数
- 如果子类不写 constructor,则会有默认的构造器,该构造器需要的参数和父类一致,并且自动调用父类构造器
补充
用 JS 制作抽象类
抽象类:一般是父类,不能通过该类创建对象
正常情况下,this 的指向,this 始终指向具体的类的对象