当前位置:   article > 正文

ES语言提升①

ES语言提升①

ES语言提升①

严格模式
  • 此处为ES5新增语法

  • 参考:https://www.runoob.com/js/js-strict.html

  • 参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode

let和const
  • ES6建议不再使用var定义变量,而使用let定义变量,const定义常量
let a = 1; // 使用let定义变量
a = 2; // 变量的值是可修改的

const b = 2; // 使用const 定义常量
b = 1; // 错误error,常量是不可修改的
  • 1
  • 2
  • 3
  • 4
  • 5
  • 开发中,均使用const,实在需要修改变量,再改为let
  • 无论let还是const,它们均解决了长久以来变量定义的问题,使用它们定义变量,具有以下特点:
    • 全局定义的变量不再作为属性添加到全局对象中
    • 在变量定义之前使用它会报错
    • 不可重复定义同名变量
    • 使用const定义变量时,必须初始化
    • 变量具有块级作用域,在代码块之外不可使用
// 注意,在for循环中使用let定义变量,变量所在的作用域是循环体,因此在循环体外不能使用。
// 另外,for循环会对该变量做特殊处理,让每次循环使用的都是一个独立的循环变量,这可以解决JS由来已久的问题。

// 过去的问题
for(var i = 0; i < 3; i++){
	setTimeout(function(){
		console.log(i)
	},1000)
}
// 输出:3 3 3

//过去的解决办法:IIFE
for(var i = 0; i < 3; i++){
	(function(i){
		setTimeout(function(){
			console.log(i)
		},1000)
	})(i)
}
// 输出:0 1 2 

//现在的做法
for(let i = 0; i < 3; i++){
	setTimeout(function(){
		console.log(i)
	},1000)
}
// 输出:0 1 2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
幂运算
2 ** 3  // 8
2 ** 4  // 16
  • 1
  • 2
字符串新增API
  • String.prototype.includes(s) => 字符串中是否包含某个子串
  • String.prototype.trim() => 去掉字符串首尾空白字符
  • String.prototype.trimStart() => 去掉字符串开始的空白字符
  • String.prototype.trimEnd() => 去掉字符串末尾的空白字符
  • String.prototype.replaceAll(s, t) => 将字符串中所有的s替换为t
  • String.prototype.startsWith(s) => 判断字符串是否以s开头
  • String.prototype.endWith(s) => 判断字符串是否以s结尾
模板字符串
  • ES6提供了一种新的字符串字面量的书写方式,即模板字符串,写法为
`字符串内容`
  • 1
  • 模板字符串可以轻松的实现换行和拼接
const user = { name: 'monica', age: 17}
const s1 = `姓名:${user.name},年龄:${user.age}`
const s2 = '姓名:' + user.name +',年龄:' + user.age + '\nmy name is ' + user.name
// s1和s2 都是 姓名:monica,年龄:17
  • 1
  • 2
  • 3
  • 4
  • 在需要换行或拼接时,模板字符串远胜于普通字符串
  • 通常,我们可以使用模板字符串拼接html
const user = { name: 'monica', age: 17}
const html = `
<div>
	<p><span class="k">姓名</span><span class="v">${user.name}</span><p>
	<p><span class="k">年龄</span><span class="v">${user.age}</span><p>
</div>
`
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

数组


for-of循环
  • ES6提供了一种爽翻天的方式遍历各种数组和伪数组
const arr = ['a', 'b', 'c']
// 过去的方式-垃圾
for(let i = 0; i < arr.length; i++){
    const item = arr[i]
    console.log(item)
}

// for of 的方式,结果一样
for(const item of arr){
    console.log(item)
}


const elements = document.querySelectorAll('.item');
//for of 的方式
for(const elem of elements){
    // elem 为获取的每一个元素
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
新增API
  • Array.isArray(target) => 判断target是否为一个数组
  • Array.from(source) => 将某个伪数组source转换为一个真数组返回
  • Array.prototype.fill(n) => 将数组的某些项设置为n
  • Array.prototype.forEach(fn) => 遍历数组,传入一个函数,每次遍历都会运行该函数
  • Array.prototype.map(fn) => 数组映射,传入一个函数,映射数组中的每一项
  • Array.prototype.filter(fn) => 数组筛选,传入一个函数,仅保留满足条件的项
  • Array.prototype.reduce(fn) => 数组聚合,传入一个函数,对数组每一项按照该函数的返回聚合
  • Array.prototype.some(fn) => 传入一个函数,判断数组中是否有至少一个通过该函数测试的项
  • Array.prototype.every(fn) => 传入一个函数,判断数组中是否所有项都能通过该函数的测试
  • Array.prototype.find(fn) => 传入一个函数,找到数组中第一个能通过该函数测试的项
  • Array.prototype.includes(item) => 判断数组中是否存在item,判定规则使用的是Object.is

对象


对象成员速写
  • 在某些场景下,ES6提供了一种更加简洁的方式书写对象成员
const name = 'xiaozhang', age = 22;
const sayHello = function(){
    console.log(`my name is ${this.name}`);
}
// 过去的方式
const user = {
    name: name,
    age: age,
    sayHello: sayHello
}

// 现在的方式:速写
const user = {
    name,
    age,
    sayHello
}

// 过去的方式
const MyMath = {
    sum: function(a, b){
        //...
    },
    random: function(min, max){
        //...
    }
}

// 速写
const MyMath = {
    sum(a, b){
        //...
    },
    random(min, max){
        //...
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
展开运算符
const arr = [4, 5, 8, 9, 0];
// 对数组的展开
Math.max(...arr); // 相当于 Math.max(4, 5, 8, 9, 0)

const o1 = {
    a: 1,
    b: 2,
}
const o2 = {
    a: 3,
    c: 4,
}
// 对对象的展开
const o3 = {
    ...o1,
    ...o2
}
/*
   o3: {
   	 a: 3,
   	 b: 2,
   	 c: 4
   }
*/

const arr1 = [1, 2, 3];
const arr2 = [4, ...arr1, 5]; // [4, 1, 2, 3, 5]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
解构
  • ES6提供了一种特殊的语法,通过该语法,可以轻松的从数组或对象中取出想要的部分
const user = {
    name: 'xiaozhang',
    age: 22,
    addr: {
        province: '广东',
        city: '广州'
    }
}

// 取出 user 中的 name 和 age 
const { name, age } = user;
console.log(name, age); // xiaozhang 22

// 取出 user 中的city
const { addr: { city } } = user
console.log(city); // 广州


const arr = [1, 2, 3, 4];
// 取出数组每一项的值,分别放到变量a, b, c, d 中
const [a, b, c, d] = arr;
// 仅取出数组下标1、2的值
const [, a, , b] = arr;
// 取出数组前两位的值,放到变量a和b中,剩下的值放到一个新数组arr2中
const [a, b, ...arr2] = arr;


let a = 1, b =2;
// 交换两个变量
[b, a] = [a, b]


// 在参数位置对传入的对象进行解构
function method({ a, b }) {
    console.log(a, b);
}
const obj = {
    a: 1,
    b: 2,
    c: 3,
};
method(obj); // 1 2


// 箭头函数也可以在参数位置进行解构
const method = ({a, b}) => {
    console.log(a, b)
}
const obj = {
    a: 1,
    b: 2,
    c: 3
}
method(obj); // 1 2


const users = {
    {name:'xiaozhang', age: 22},
    {name: 'xiaolai', age: 18}
}
// 在遍历时进行解构
for(const {name, age} of users){
    console.log(name, age)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
属性描述符
  • 对于对象中的每个成员,JS使用属性描述符来描述它们
const user = {
    name: 'xiaozhang',
    age: 22
}
  • 1
  • 2
  • 3
  • 4
  • 上面的对象,在JS内部被描述为
{
    // 属性 name 的描述符
    name: {
        value: 'xiaozhang',
        configurable: true, // 该属性的描述符是否可以被重新定义
        enumerable: true, // 该属性是否允许被遍历,会影响for-in循环
        writable: true //该属性是否允许被修改
    },
    // 属性 age 的描述符
    age: {
        value: 22,
        configurable: true, // 该属性的描述符是否可以被重新定义
        enumerable: true, // 该属性是否允许被遍历,会影响for-in循环
        writable: true //该属性是否允许被修改
    },
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • ES5提供了一系列的API,针对属性描述符进行操作
  1. Object.getOwnPropertyDesciptor(obj, propertyName) => 该方法用于获取一个属性的描述符
const user = {
    name: 'xiaozhang',
    age: 22
}

Object.getOwnPropertyDescriptor(user, 'name');
/*
{
	 value: 'xiaozhang',
     configurable: true, // 该属性的描述符是否可以被重新定义
     enumerable: true, // 该属性是否允许被遍历,会影响for-in循环
     writable: true //该属性是否允许被修改
}
*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  1. Object.defineProperty(obj, propertyName, descriptor) => 该方法用于定义某个属性的描述符
const user = {
    name: 'xiaozhang',
    age: 22
};

Object.defineProperty(obj, 'name', {
    value: 'xiaolai', // 将其值进行修改
   	enumerable: false, // 让该属性不能被遍历
    writable: false // 让该属性无法被重新赋值
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
getter 和 setter
  • 属性描述符中有两个特殊的配置,分别为getset ,通过它们,可以把属性的取值和赋值变为方法调用
const obj = {};
Object.defineProperty(obj, 'a', {
    get(){ // 读取属性a时,得到的是该方法的返回值
        return 1;
    },
    set(val){ // 设置属性a时,会把值传入val,调用该方法
        console.log(val)
    }
})

console.log(obj.a);  // 输出:1
obj.a = 3; // 输出:3
console.log(obj.a); // 输出:1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
键值对
  • Object.keys(obj) => 获取对象的属性名组成的数组
  • Object.values(obj) => 获取对象的值组成的数组
  • Object.entries(obj) => 获取对象属性名和属性值组成的数组
  • Object.fromEntries(entries) => 将属性名和属性值的数组转换为对象
const user = {
    name: 'xiaozhang',
    age: 22
}
Object.keys(user); // ["name", "age"]
Object.values(user); // ["xiaozhang", 22]
Object.entries(user); // [ ["name", "xiaozhang"], ["age", 22] ]
Object.fromEntries([ ["name", "xiaozhang"], ["age", 22] ]); // {name:'xiaozhang', age:22}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
冻结(了解即可)
  • 使用Object.freeze(obj) 可以冻结一个对象,该对象的所有属性均不可更改
const obj = {
    a: 1,
    b: {
        c: 3,
    },
};

Object.freeze(obj); // 冻结对象obj

obj.a = 2; // 不报错,代码无效
obj.k = 4; // 不报错,代码无效
delete obj.a; // 不报错,代码无效
obj.b = 5; // 不报错,代码无效

obj.b.c = 5; // b对象没有被冻结,有效

console.log(obj); // {a: 1, b: { c: 5 }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 可以使用Object.isFrozen来判断一个对象是否被冻结
相同性判定
  • Object.is 方法,可以判断两个值是否相同,它和=== 的功能基本一致,区别在于
    • NaN 和 NaN 相等
    • +0 和 -0 不相等
Object.is(1, 2); // false
Object.is("1", 1); // false
Object.is(NaN, NaN); // true
Object.is(+0, -0); // false
  • 1
  • 2
  • 3
  • 4
Set
  • Set 是一种数据集合,用于保存一系列唯一的值
// 数组去重:获取一个不包含重复项的新数组
const arr = [1, 4, 5, 6, 7, 8, 1, 2];
const newArr = [...new Set(arr)];
console.log(newArr); // [1, 4, 5, 6, 7, 8, 2]
  • 1
  • 2
  • 3
  • 4
Map
  • Map是一种数据集合,用于保存一系列键值对(key-value pair),其中,键是唯一
  • 键可以是任何类型
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/248648
推荐阅读
相关标签
  

闽ICP备14008679号