变量声明(let)
基础使用
//1. 声明变量时不能重复声明
let temp = 1
let temp = 2
// Uncaught SyntaxError: Identifier 'temp' has already been declared
//2. let声明的变量拥有块级作用域,不影响作用域链
{
let JuiceBox = '果汁盒'
}
console.log(juiceBox);
// Uncaught ReferenceError: ljuiceBox is not defined
//3. 与var相比,不存在变量提升
console.log(a); // Uncaught ReferenceError: Cannot access 'a' before initialization
console.log(b); // undefined
let a = 'JuiceBox'
var b = 'JuiceBox'
经典场景
使用for
循环遍历一些DOM元素时,点击改变背景颜色
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 25px;
height: 25px;
text-align: center;
}
</style>
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</body>
<script>
let items = document.getElementsByTagName('div')
// 使用var声明i,点击所有的div只会让最后一个改变颜色,
// i没有作用域,当触发点击回调函数时,此时的i的值就是循环结束的值(window.i)如果想实现效果要使用闭包或者使用this来指向当前DOM元素
for (var i = 0; i < items.length - 1; i++) {
items[i].onclick = function() {
items[i].style.background = '#bfa'
}
}
// 使用let声明i,只有点击对应的第的div才会改变对应的颜色
// 此时i是由作用域的,每个回调函数拿到的是对应循环作用域的i的值
for (let i = 0; i < items.length; i++) {
items[i].onclick = function() {
items[i].style.background = '#bfa'
}
}
</script>
变量声明(const)
基础使用
<script>
//1. 声明的同时必修赋初始值
const JuiceBox
// index.html:52 Uncaught SyntaxError: Missing initializer in const declaration
//2. 常量一般使用大写
//3. 常量的值不能修改(数组和对象除外,因为地址没变)
const JuiceBox = '果汁盒'
JuiceBox = '9527'
// index.html:59 Uncaught TypeError: Assignment to constant variable.
const temp = {name:'JuiceBox'}
temp.name = { name: '果汁盒' }
console.log(temp);
// {name:"果汁盒"}
//4. 块级作用域
{
const JuiceBox = '果汁盒'
}
console.log(JuiceBox);
// index.html:60 Uncaught ReferenceError: JuiceBox is not defined
</script>
变量的解构赋值
ES6允许按照一定的规则从数组和对象中提取值,对变量进行赋值
//1. 数组解构
const xy = ['唐三藏', '孙悟空', '猪八戒', '沙悟净', '白龙马']
let [tang, sun, zhu, sha, bai] = xy
console.log(tang) // 唐三藏
console.log(sun) // 孙悟空
console.log(zhu) // 猪八戒
console.log(sha) // 沙悟净
console.log(bai) // 白龙马
//2. 对象解构
const JuiceBox = {
name: '果汁盒',
age: 23,
skill: function() {
console.log('摸鱼技巧')
}
}
let { name, age, skill } = JuiceBox
console.log(name) // '果汁盒'
console.log(age) // 23
skill() // '摸鱼技巧'
// 结构赋值取别名
let {skill:moYuSkill} = JuiceBox
moYuSkill() // '摸鱼技巧'
模板字符串(``)
基础使用
//1. 模板字符串里会保留空格和缩进以及换行符等特殊格式与字符
let str = `<div>
<h1></h1>
</div>`
console.log(str);
/*
<div>
<h1></h1>
</div>
*/
//2. 可以直接拼接变量${变量}
let JuiceBox = '果汁盒'
let temp = `JuiceBox就是${JuiceBox}`
console.log(temp) // JuiceBox就是果汁盒
有关对象的简化写法
let name = '果汁盒'
let skill = function(){
console.log('我的技能是摸鱼');
}
let JuiceBox = {
name,
skill,
moYuSkill(){
console.log('进阶摸鱼技能');
}
}
箭头函数
因为箭头函数的this是静态的,始终指向声明函数所在的作用域下的this的值,所以它的应用场景普遍用于当回调函数中this的指向不方便我们操作时的情况,例如定时器延时器,使用数组的filter
方法时等。
//基本用法
let fn = (a, b) => {
return a + b
}
console.log(fn(1, 1)) // 2
//1. 箭头函数的this是静态的,始终指向声明函数所在的作用域下的this的值
window.name = 'JuiceBox'
function getName() {
console.log(this.name);
}
let getName1 = () => {
console.log(this.name);
}
const JuiceBox = {
name: '果汁盒'
}
getName() //JuiceBox
getName1() //JuiceBox
getName.call(JuiceBox) //果汁盒
getName1.call(JuiceBox) //JuiceBox
//2. 不能作为构造函数去实例化对象
let Person = (name,age) =>{
this.name = name
this.age = age
}
let people = new Person('果汁盒',23) // Uncaught TypeError: Person is not a constructor
//3. 不能使用argument
//4. 简写当形参还有一个时可以省略小括号。当函数代码体只有一条语句的时候,若有return也需要省略
let square = n => n*n
console.log(square(3)) // 9
函数形参赋初始值
function add(a = 1, b = 2, c = 3) {
return a + b + c
}
console.log(add()) // 6
console.log(add(3, 3)) // 9
// 与解构赋值结合
function importPerson({ name = '默认名字', age = '默认年龄', skill = '默认技能' }) {
console.log(name);
console.log(age);
console.log(skill);
}
importPerson({
name: '果汁盒',
age: 23,
skill
})
扩展运算符(…)
const xy = ['唐三藏', '孙悟空', '猪八戒', '沙悟净', '白龙马',]
console.log(...xy) // 唐三藏 孙悟空 猪八戒 沙悟净 白龙马
// 用于数组合并或者克隆(浅拷贝)
const a = [1, 2, 3,]
const b = [4, 5, 6,]
const c = [...a,...b]
console.log(c) // (6) [1, 2, 3, 4, 5, 6]
//将伪数组转换为真的数组,同上
rest参数替代argument
function xy() {
console.log(arguments);
}
xy('唐三藏', '孙悟空', '猪八戒', '沙悟净', '白龙马') // arguments是伪数组(对象)
function xy1(...args) {
console.log(args);
}
xy1('唐三藏', '孙悟空', '猪八戒', '沙悟净', '白龙马') // rest是数组
新的数据类型Symbol
- Symbol的值是唯一的,用来解决命名冲突问题
- Symbol的值不能与其他数据进行运算
- Symbol定义的对象属性不能用
for...in
遍历,可以使用Reflect.ownKeys
来获取对象的所有键名
基本使用
//1. 创建Symbol
let s = Symbol()
console.log(s, typeof s) // Symbol() "symbol"
let s1 = Symbol('Juicebox')
let s2 = Symbol('Juicebox')
console.log(s1, typeof s1) // Symbol(Juicebox) "symbol"
console.log(s1 === s2) // false
//2. Symbol.for创建
let s3 = Symbol.for('Juicebox')
let s4 = Symbol.for('Juicebox')
console.log(s3, typeof s3)
console.log(s3 === s4) // true
//3. 不能与其他数据做运算包括Symbol类型的
使用场景
- 不知道某个对象的属性名是否被使用时
迭代器
- 迭代器是一种接口,ES6中迭代器主要供
for...of
使用,自定义数据遍历加处理。
生成器
- 解决异步编程的函数
// 解决回调地狱(yield将代码分割使其按照顺序执行)
// 调用生成器函数
let iterator = go()
iterator.next()
function one() {
setTimeout(() => {
let data = 111111
iterator.next(data)
}, 1000);
}
function two() {
setTimeout(() => {
let data = 222222
iterator.next(data)
}, 2000);
}
function three() {
setTimeout(() => {
let data = 333333
iterator.next(data)
}, 3000);
}
function* go() {
let temp = yield one()
console.log(temp);
let temp1 = yield two()
console.log(temp1);
let temp2= yield three()
console.log(temp2);
}
Promise(处理异步编程)
- Promise从语法上来看一个构造函数,用来封装异步操作,能获取异步操作失败和成功的结果
const example = new Promise(function(resolve,rejct){
setTimeout(() => {
let data = '数据库返回的数据'
// resolve(data)
rejct('error')
}, 2000);
})
//通过.then()里的两个函数处理异步操作的结果。
//若使用的是resolve方法则会默认调用第一个方法,反之调用第二个,也可使用.catch()去做错误的处理
example.then(function(value){
console.log(value);
},function(reason){
console.log(reason);
})
Set
- 实现了iterator接口可以使用
for...of
进行遍历,它类似于数组,但是值都是唯一的。
属性/方法名 | 描述 |
---|---|
size | 返回集合的元素个数 |
add | 增加一个新元素,返回当前集合 |
delete | 删除元素,返回boolean值 |
has | 检测集合是否包含某个元素,返回boolean值 |
clear | 清空集合 |
let s = new Set()
let s1 = new Set([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5])
console.log(s) // Set(0) {}
console.log(s, s1) // Set(5) {1, 2, 3, 4, 5} Set会自动去重
console.log(s1.size); // 5
s1.add(6)
console.log(s1) // Set(6) { 1, 2, 3, 4, 5, 6 }
s1.delete(6) // Set(5) {1, 2, 3, 4, 5}
console.log(s1.has(1)) // true
s1.clear()
console.log(s1); // Set(0) {}
Map
- 类似于对象,但是属性名不限制于字符串可以是其他所有数据类型,它是键值对的形式存储,实现了iterator接口可以使用
for...of
进行遍历。
属性/方法名 | 描述 |
---|---|
size | 返回Map元素个数 |
set(键名,键值) | 增加一个新元素,返回当前Map |
get(键名) | 返回键名对象的值 |
has | 检测Map中是否包含某个元素,返回boolean值 |
clear | 清空Map |
let example = new Map()
let key = {
name: 'JuiceBox'
}
example.set(key,['juicebox','果汁盒'])
console.log(example);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fv2L36tO-1625563558205)(E:\note\img\image-20210630121415063.png)]
class
基础使用
//创建Person类
class Person {
// 构造方法
constructor(name,age) {
this.name = name
this.age = age
}
// 方法必须使用ES6语法
introduction(){
console.log(`我叫${this.name},今年${this.age}岁`);
}
}
//若给Person添加属性例如Person.xxx = xxx,这种属性是不属于实例对象的,是属于这个类的
let juiceBox = new Person('果汁盒','18')
juiceBox.introduction() // 我叫果汁盒,今年18岁
继承
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
introduction() {
console.log(`我叫${this.name},今年${this.age}岁`);
}
}
class GreenHand extends Person {
constructor(name, age, skill){
super(name, age)
this.skill = skill
}
}
let juiceBox = new GreenHand('果汁盒',18,'摸鱼')
juiceBox.introduction() // 我叫果汁盒,今年18岁
子类重写父类方法
- 子类是不能去调用同名的父类方法的,同名时只能调用子类自己的同名方法
getter与setter
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
get getName() {
return this.name
}
set setName(newValue) {
this.name = newValue
}
introduction() {
console.log(`我叫${this.name},今年${this.age}岁`);
}
}
let juiceBox = new Person()
juiceBox.setName = 9527
console.log(juiceBox.getName);
数值的扩展
-
Number.EPSILON
是JavaScript表示的最小精度。 -
二进制和八进制
let a = 0b1010 let o = 0o777 let d = 99 let x = 0xff console.log(a, o, d, x); // 10 511 99 255
-
Number.isFinite()
检测一个数是否为有限数 -
Number.isNaN()
检测数值是否为NaN -
Number.parseFloat()
与Number.parseInt()
将字符转换为数字 -
Number.isInteger()
判断一个数是否为整数 -
Math.trunc()
去掉数值的小数点 -
Math.sign()
判断数值为正数,负数还是0
对象方法的扩展
//1. Object.is(value1, value2)判断两个值是否完全相等
console.log(NaN === NaN) // false
console.log(Object.is(NaN, NaN)) // true
//2. Object.assign(value1,value2)对象的合并,value2会把value1覆盖掉
//3. Object.setPrototypeOf(value1,value2),设置value2位value1的原型对象
// Object.getPrototypeOf(),获取原型对象
ES6模块化
- 模块化的优点:
- 防止命名冲突
- 代码复用
- 高维护性
- ES6之前的模块化规范:
- CommonJS
- AMD
- CMD
- ES6模块化语法
export
用于规定模块对外接口import
用于导入其他模块提供的功能
Math.sign()
判断数值为正数,负数还是0
对象方法的扩展
//1. Object.is(value1, value2)判断两个值是否完全相等
console.log(NaN === NaN) // false
console.log(Object.is(NaN, NaN)) // true
//2. Object.assign(value1,value2)对象的合并,value2会把value1覆盖掉
//3. Object.setPrototypeOf(value1,value2),设置value2位value1的原型对象
// Object.getPrototypeOf(),获取原型对象
ES6模块化
- 模块化的优点:
- 防止命名冲突
- 代码复用
- 高维护性
- ES6之前的模块化规范:
- CommonJS
- AMD
- CMD
- ES6模块化语法
export
用于规定模块对外接口import
用于导入其他模块提供的功能