02-ES6新语法

1. ES6 Proxy与Reflect

1.1 概述

Proxy 与 Reflect 是 ES6 为了操作对象引入的 API 。

Proxy 可以对目标对象的读取、函数调用等操作进行拦截,然后进行操作处理。它不直接操作对象,而是像代理模式,通过对象的代理对象进行操作,在进行这些操作时,可以添加一些需要的额外操作。

Reflect 可以用于获取目标对象的行为,它与 Object 类似,但是更易读,为操作对象提供了一种更优雅的方式。它的方法与 Proxy 是对应的。

1.2 基本用法

1.2.1 Proxy(代理)

proxy,代理,使用代理,我们可以操作对象时,需要先经过代理,才能到达对象,这样就可以起到'拦截'的作用。

一个 Proxy 对象由两个部分组成: target 、 handler 。在通过 Proxy 构造函数生成实例对象时,需要提供这两个参数。 target 即目标对象, handler 是一个对象,声明了代理 target 的指定行为,拦截过滤代理操作的。

let target = {
    name: 'zhangmeili',
    age: 24
}
let handler = {
    get: function(target, key) {
        console.log('getting '+key);
        return target[key]; // 不是target.key
    },
    set: function(target, key, value) {
        console.log('setting '+key);
        target[key] = value;
    }
}
let proxy = new Proxy(target, handler)
proxy.name     // 实际执行 handler.get
proxy.age = 25 // 实际执行 handler.set
总结proxy的用处:

实现拦截和监视外部对对象的访问。

降低函数和类的复杂度,优雅的写出代理代码。

在复杂操作前对操作进行校验或对所需资源进行管理。

场景:
  1. 抽离校验模块。

  2. 私有属性。

  3. 预警和拦截。

  4. 过滤操作。

  5. 中断代理。

1.2.2 Reflect(反射)

ES6 中将 Object 的一些明显属于语言内部的方法移植到了 Reflect 对象上(当前某些方法会同时存在于 Object 和 Reflect 对象上),未来的新方法会只部署在 Reflect 对象上。

Reflect 对象对某些方法的返回结果进行了修改,使其更合理。

Reflect 对象使用函数的方式实现了 Object 的命令式操作。

静态方法

Reflect.get(target, key, receiver)

查找并返回 target 对象的 key属性。

let person = {
    name: "zhangmeili",
    age: 24,
    get info(){
        return this.name + this.age;
    }
}
Reflect.get(person, 'name'); // "zhangmeili"
 
// 当 target 对象中存在 name 属性的 getter 方法, getter 方法的 this 会绑定 // receiver
let receiver = {
    name: "wangshuai",
    age: 20
}
Reflect.get(person, 'info', receiver); // wangshuai
 
// 当 name 为不存在于 target 对象的属性时,返回 undefined
Reflect.get(person, 'birth'); // undefined
 
// 当 target 不是对象时,会报错
Reflect.get(1, 'name'); // TypeError
​
​
let person = {
    name: "zhangmeili",
    age: 24,
    get info() {
        return this.name + this.age;
    }
};
Reflect.set(person,'sex','男');
console.log(person);
总结reflect的用处

reflect有的方法object都有,es6希望数据和逻辑代码分离,那么object就是纯数据,所有的逻辑都放到reflect上,对象对某些方法的返回结果进行了修改,使其更合理。

场景:
  1. 当object的工具类来用。
1.2.3 组合使用

Reflect 对象的方法与 Proxy 对象的方法是一一对应的。所以 Proxy 对象的方法可以通过调用 Reflect 对象的方法获取默认行为,然后进行额外操作。

let person = {
    name: "zhangmeili",
    age: 24
}
let handler = {
    get: function(target, key){
        console.log("getting "+key);
        return Reflect.get(target,key);
    },
    set: function(target, key, value){
        console.log("setting "+key+" to "+value)
        Reflect.set(target, key, value);
    }
}
let proxy = new Proxy(person, handler)
// 设置
proxy.name = "wangshuai"
//获取
console.log(proxy.name);

2. ES6 字符串

2.1 子串的识别

ES6 之前判断字符串是否包含子串,用 indexOf 方法,ES6 新增了子串的识别方法。

  • includes():返回布尔值,判断是否找到参数字符串。

  • startsWith():返回布尔值,判断参数字符串是否在原字符串的头部。

  • endsWith():返回布尔值,判断参数字符串是否在原字符串的尾部。

以上三个方法都可以接受两个参数,需要搜索的字符串,和可选的搜索起始位置索引。

let string = "apple,banana,orange";
string.includes("banana");     // true
string.startsWith("apple");    // true
string.endsWith("apple");      // false
string.startsWith("banana",6)  // true

注意:

  • 这三个方法只返回布尔值,如果需要知道子串的位置,还是得用 indexOf 和 lastIndexOf 。

  • 这三个方法如果传入了正则表达式而不是字符串,会抛出错误。而 indexOf 和 lastIndexOf 这两个方法,它们会将正则表达式转换为字符串并搜索它。

2.2 字符串重复

repeat():返回新的字符串,表示将字符串重复指定次数返回。

console.log("Hello,".repeat(2));  // "Hello,Hello,"

2.3 字符串补全

  • padStart(targetLength [, padString]):返回新的字符串,表示用参数字符串从头部(左侧)补全原字符串。

  • padEnd(targetLength [, padString]):返回新的字符串,表示用参数字符串从尾部(右侧)补全原字符串。

以上两个方法接受两个参数,第一个参数是指定生成的字符串的最小长度,第二个参数是用来补全的字符串。如果没有指定第二个参数,默认用空格填充。

console.log("h".padStart(5,"o"));  // "ooooh"
console.log("h".padEnd(5,"o"));    // "hoooo"
console.log("h".padStart(5));      // "    h"

2.4 模板字符串

模板字符串相当于加强版的字符串,用反引号 `,除了作为普通字符串,还可以用来定义多行字符串,还可以在字符串中加入变量和表达式。

let string = `Hello'\n'world`;
console.log(string); 
// "Hello'"
// "'world"
​
//模板字符串  ``反引号
var num = 123
var fn = function () {
  return "hello"
}
let str66 = "hello \n everyone"
console.log(str66);
​
let str666 = `hello everyone ${num + 10} ${fn()}`
console.log(str666);
​
let str2=`hello`

3. ES6 数值

3.1 数值的表示(了解)

二进制表示法新写法: 前缀 0b 或 0B 。

console.log(0b11 === 3); // true
console.log(0B11 === 3); // true

八进制表示法新写法: 前缀 0o 或 0O 或0。

console.log(0o11 === 9); // true
console.log(0O11 === 9); // true

3.2 Number对象新方法

  • Number.isNaN():用于检查一个值是否为 NaN 。

    console.log(Number.isNaN(NaN)); // true
    console.log(Number.isNaN('true'/0)); // true

    // 在全局的 isNaN() 中,以下皆返回 true,因为在判断前会将非数值向数值转换
    // 而 Number.isNaN() 不存在隐式的 Number() 类型转换,非 NaN 全部返回 false
    Number.isNaN("NaN"); // false
    Number.isNaN(undefined); // false
    Number.isNaN({}); // false
    Number.isNaN("true"); // false

3.2 指数运算符(了解)

1 ** 2; // 1
// 右结合,从右至左计算
2 ** 2 ** 3; // 256
// **=
let power  = 2;
power  **= 3; // 8

3.3 parseInt(string, radix)方法补充

parseInt(string, radix)
string 必需。要解析的字符串。
radix 可选。代表要使用的数字系统的数字(从 2 到 36)。如果是0,radix被假定10(十进制)

面试题:

["1", "2", "3"].map(parseInt) 为何返回[1,NaN,NaN]?
//解析:
arr.map(function(value,index){})  
​
parseInt('1',0); //1
​
parseInt('2',1);//NaN
​
parseInt('3',2);//NaN
​
​
//例如
parseInt('11',16);//17

4. ES6 对象(重点)

4.1 属性的简洁表示法

const age = 18;
const name = "zhangmeili";
const person = {age, name};
console.log(person) //{age: 18, name: "zhangmeili"}
//等同于
const person = {age: age, name: name}

4.2 方法名也可以简写

const person = {
  sayHi(){
    console.log("Hi");
  }
}
person.sayHi();  //"Hi"
//等同于
const person = {
  sayHi:function(){
    console.log("Hi");
  }
}
person.sayHi();//"Hi"

4.3 属性名表达式

ES6允许用表达式作为属性名,但是一定要将表达式放在方括号[ ]内。

const obj = {
 ["he"+"llo"](){
   return "Hi";
  }
}
obj.hello();  //"Hi"

注意点:属性的简洁表示法和属性名表达式不能同时使用,否则会报错。

const hello = "Hello";
const obj = {
 [hello]
};
​
//SyntaxError: Unexpected token }
console.log(obj);
 
const hello = "Hello";
const obj = {
 [hello+"2"]:"world"
};
​
//{Hello2: "world"}
console.log(obj);
​

4.4 扩展运算符-对象中的用法(重点)

扩展运算符(...)用于取出参数对象所有可遍历属性然后拷贝到当前对象。

  • 基本用法-拷贝对象

    let person = {name: "zhangmeili", age: 18};
    let pcopy = { ...person };
    console.log(pcopy); //{name: "zhangmeili", age: 15}

  • 可用于合并两个对象

    let age = {age: 18};
    let name = {name: "zhangmeili"};
    let person= {...age, ...name};
    console.log(person) //{age: 18, name: "zhangmeili"}

注意:

自定义的属性和扩展运算符对象里面属性的相同的时候:自定义的属性在扩展运算符后面,则扩展运算符对象内部同名的属性将被覆盖掉。

4.5 对象的新方法

Object.is(value1, value2) 用来比较两个值是否严格相等,与(===)基本类似。

Object.is("q","q");      // true
Object.is(1,1);          // true
Object.is([1],[1]);      // false
Object.is({q:1},{q:1});  // false
Object.is(NaN, NaN);// true

5. ES6 数组

5.1 数组创建

  • Array.of()将参数中所有值作为元素形成数组。

    console.log(Array.of(1, 2, 3, 4)); // [1, 2, 3, 4]

复制代码
 
// 参数值可为不同类型
console.log(Array.of(1, '2', true)); // [1, '2', true]
复制代码
 
// 参数为空时返回空数组
console.log(Array.of()); // []
  • Array.from()将类数组对象或可迭代对象转化为数组。

    // 浅拷贝数组
    var arr=[1,2,3];
    console.log(Array.from(arr)); //[1,2,3]

    // 参数为数组,返回与原数组一样的数组
    console.log(Array.from([1, 2])); // [1, 2]

5.2 数组的新方法

  • arr.findIndex(callback)查找数组中符合条件的元素索引,若有多个符合条件的元素,则返回第一个元素索引。

    let arr = Array.of(2,5,6,-7,2);
    console.log(arr.findIndex(function(value,index){
    if(value < 0){
    return index;
    }
    }));

  • arr.flat([depth]) 嵌套数组转指定深度的数组。

    let arr = [1,2,4,[5,6,77,[2,3,45,'你好啊']]];
    arr2 = arr.flat(1);
    console.log(arr2);

5.3 扩展运算符-数组中的用法(重点)

  • 复制数组

    let arr1 = [1, 2];
    let arr2 = [...arr1];
    console.log(arr2); // [1, 2]

  • 合并数组

    let arr = [1,2,4];
    let arr2 = ["你好","world",'qqqq',true];
    let arr3 = [...arr,...arr2];
    console.log(arr3);

  • 将伪数组转换为数组

    var boxes = document.querySelectorAll('div');
    console.log(boxes);
    console.log([...boxes]);

5.4 剩余运算符和扩展运算符的区别

剩余运算符收集 这些集合数据,扩展运算符 是将数组或对象拆分成元素的集合 ,它们是相反的

//剩余运算符收集数据
function fun1(a, b, ...arr1) {
    console.log(arr1.length);
}
fun1(1,23,4);
​
//扩展运算符--合并对象/数组
let age = {age: 18};
let name = {name: "zhangmeili"};
let person= {...age, ...name};
console.log(person) //{age: 18, name: "zhangmeili"}
相关推荐
℘团子এ3 分钟前
vue3中如何上传文件到腾讯云的桶(cosbrowser)
前端·javascript·腾讯云
学习前端的小z9 分钟前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
彭世瑜32 分钟前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund40433 分钟前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish34 分钟前
Token刷新机制
前端·javascript·vue.js·typescript·vue
小五Five35 分钟前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序35 分钟前
vue3 封装request请求
java·前端·typescript·vue
临枫54136 分钟前
Nuxt3封装网络请求 useFetch & $fetch
前端·javascript·vue.js·typescript
前端每日三省37 分钟前
面试题-TS(八):什么是装饰器(decorators)?如何在 TypeScript 中使用它们?
开发语言·前端·javascript
小刺猬_98537 分钟前
(超详细)数组方法 ——— splice( )
前端·javascript·typescript