ECMAScript 6 之二

目录

2.6 Symbol

2.7 Map 和 Set

2.8 迭代器和生成器

2.9 Promise对象

2.10 Proxy对象

2.11 async的用法

2.22 类class

2.23 模块化实现


2.6 Symbol

        原始数据类型,它表示是独一无二的值。它属于 JavaScript 语言的原生数据类型之一,其他数据类型是:undefinednull、布尔值(Boolean)、字符串(String)、数值(Number)、大整数(BigInt)、对象(Object)。

        Symbol值通过Symbol() 函数生成。

        最大的用途:用来定义对象的私有变量,用Symbol定义的对象中的变量,取值时一定要用 [变量名]

let s1 = Symbol('s1');
let obj = {[s1]: '张三'
}
console.log(obj[s1]); // 张三
console.log(obj.s1); // undefined

         Symbol值作为属性名,遍历对象的时候,该属性不会出现在for..in,for...of循环中,也不会被Object.keys()等返回。它有一个Object.getOwnPropertySymbols()方法,获取指定对象的所有Symbol属性名,该方法返回一个数组,成员是当前对象的所有用作属性名的Symbol值。

        另一个API:Reflect.ownKeys() 方法,可以返回所有类型的键名,包括常规键名和 Symbol 键名。

let s1 = Symbol('s1');
let obj = {[s1]: '张三',[Symbol('s2')]: '李四',s3: '王五'
}
// console.log(obj[s1]); // 张三
// console.log(obj.s1); // undefined// 获取symbol声明的属性名(作为对象的key)
let s = Object.getOwnPropertySymbols(obj);
console.log(s); // [Symbol(s1), Symbol(s2)]
let m = Reflect.ownKeys(obj);
console.log(m); // ['s3', Symbol(s1), Symbol(s2)]

注意:

1、Symbol() 函数不能使用new命令,否则会报错,生成的Symbol是一个原始类型的值,不是一个对象;

2、 由于Symbol值不是对象,不能添加属性。

2.7 Map 和 Set

一、Set 集合

1、Set 集合:表示一个无重复值的有序列表,类似于数组,本身是一个构造函数,用来生成Set数据结构。

let set = new Set();
console.log(set);

 2、方法:

1)添加元素

set.add(2);
set.add('4');
set.add('4');
set.add([1,2,3]);
console.log(set); // {2, "4", [1,2,3]}

2)删除元素

// 删除元素
set.delete(2);
console.log(set); //{ "4", [1,2,3]}

3)校验某个值是否在set中,存在true,不存在false

console.log(set.has('4')); //true

4)集合的长度

console.log(set.size); //2

 5)将set集合转化为数组

// 将set转换成数组
let set2 = new Set([1,1,2,3,3,4,5,5]);
let arr = [...set2];
console.log(arr); // [1, 2, 3, 4, 5]

6)清除所有成员,没有返回值

set.clear();

7)WeakSet      

        WeakSet结构与Set类似,也是不重复的值的集合。可以用于储存DOM节点,而不用担心这些节点从文档移除时会引发内存泄漏。

        (1)WeakSet 的成员只能是对象,而不能是其他类型的值;

        (2)WeakSet 中的对象都是弱引用;

        (3)不可迭代;

        (4)没有forEach();

        (5)没有size属性。

let set3 = new WeakSet(), obj = {};
set3.add(obj);
// 释放当前的资源
obj = null;
console.log(set3);

二、Map 类型

        Map类型是键值对的有序列表,键和值是任意类型,类似于对象。

let map = new Map();
map.set('name','张三');
map.set('age',20);
console.log(map); // {'name' => '张三', 'age' => 20}
console.log(map.get('name')); // 张三
map.has('name'); // true
map.delete('name');
console.log(map); //{'age' => 20}
map.clear();
console.log(map); //{size: 0}map.set(['a',[1,2,3]],'hello');
console.log(map); //{Array(2) => 'hello'}let m = new Map([['a',1],['c',2]]);
console.log(m); //{'a' => 1, 'c' => 2}

 遍历方法:

1、.keys()  返回键名的遍历器

2、.values() 返回键值的遍历器

3、.entries() 返回所有成员的遍历器

4、.forEach() 遍历Map的所有成员

let m = new Map([['A',1],['B',2]]
)
for(let key of m.keys()){console.log(key); 
}
// A
// Bfor(let val of m.values()){console.log(val);
}
// 1
// 2 
for(let item of m.entries()){console.log(item);console.log(item[0],item[1]);
}
// ['A', 1]
// A 1
// ['B', 2]
// B 2
m.forEach((val,key,map)=>{console.log(val,key,map);
})
// 1 'A' {'A' => 1, 'B' => 2}
// 2 'B' {'A' => 1, 'B' => 2}

 .forEach() 方法可以接受第二个参数,用来绑定this

const reporter = {report: function(key, value) {console.log("Key: %s, Value: %s", key, value);}
};m.forEach(function(value, key, map) {this.report(key, value);
}, reporter);
// Key: A, Value: 1
// Key: B, Value: 2

 Map 结构转为数组结构,使用扩展运算符

let m0 = new Map([[1,'one'],[2,'two'],[3,'three']
]);
console.log([...m0.keys()]); //[1, 2, 3]
console.log([...m0.values()]); //['one', 'two', 'three']
console.log([...m0.entries()]); //[[1,'one'], [2, 'two'], [3, 'three']]
console.log([...m0]); //[[1,'one'], [2, 'two'], [3, 'three']]

2.8 迭代器和生成器

一、 Iterator 迭代器

        一种新的遍历机制,两个核心:

1. 迭代器是一个接口,能快捷的访问数据,通过Symbol.iterator来创建迭代器,通过迭代器的next() 获取迭代之后的结果;

2. 迭代器是用于遍历数据结构的指针(数据库的游标)。

const items = ['one','two','three','four'];
const ite = items[Symbol.iterator]();
console.log(ite.next()); //{value: 'one', done: false}  done如果为false表示遍历继续,如果为true表示遍历完成
console.log(ite.next()); // {value: 'two', done: false}
console.log(ite.next()); // {value: 'three', done: false}
console.log(ite.next()); // {value: 'four', done: false}
console.log(ite.next()); // {value: undefined, done: true}

二、生成器 Generator 

        可以通过yield关键字,将函数挂起,为改变执行流程提供了可能,同时为做异步编程提供了方案。

        与普通函数的区别:

        1. function 后面,函数名之前有个 *

        2. 只能在函数内部使用 yield 表达式,让函数挂起。

function* func(){yield 2;yield 3;
}
// 返回一个遍历器对象,可以调用next()
let fn = func();
console.log(fn.next());//{value: 2, done: false}
console.log(fn.next());//{value: 3, done: false}
console.log(fn.next());//{value: undefined, done: true}// generator函数是分段执行的,yield语句是暂停执行,而next() 是恢复执行

function* add(){let x = yield '2';// x 不是yield '2'的返回值,它是next() 调用,恢复当前 yield 执行传入的实参console.log("one:",x);let y = yield '3';console.log("two:",y);return x+y;
}
const fn = add();
console.log(fn.next()); // {value: '2', done: false}
console.log(fn.next(20)); // {value: '3', done: false}
console.log(fn.next(30)); // {value: 50, done: true}
// 使用场景:为不具备Interator接口的对象提供了遍历的操作
function* objectEntries(obj){// 获取对象所有的key保存到数组 const propKeys = Object.keys(obj);for(const propkey of propKeys){yield [propkey,obj[propkey]]}
}
const obj = {name: '张三',age: 18
}
obj[Symbol.iterator] = objectEntries;
console.log(obj);
for(let [key,value] of objectEntries(obj)){console.log(`${key}:${value}`);
}
//name:张三
//age:18

2.9 Promise对象

一、介绍

        Promise 是异步编程的一种解决方案,它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。

        相当于一个容器,保存着未来才会结束的事件(异步操作)的一个结果。

        各种异步操作都可以用同样的方法进行处理 axios。

特点:

1、对象的状态不受外界影响,处理异步操作三个状态:pending(进行中)、fulfilled(resolved)(成功)、rejected(失败)。

2、pending(进行中)、fulfilled(resolved)(成功)、rejected(失败)一旦状态改变,就不会再变,任何时候都可以得到这个结果。

let pro = new Promise(function(resolved,rejected){// 执行异步操作
});
console.log(pro);

 二、基本使用

let pro = new Promise(function(resolved,rejected){// 执行异步操作let res = {//code: 200,code: 201,data:{name: '张三',age: 20},error:'失败了!'}setTimeout(()=>{if(res.code == 200){resolved(res.data);}else{rejected(res.error);}},1000)
});
console.log(pro);
// then()方法
// 第一个参数是resolve回调函数,第二个参数是可选的,是reject状态回调函数
// 返回的是一个新的promise实例,可以采用链式编程
pro.then((val)=>{console.log(val); //{name: '张三', age: 20}
},(err)=>{console.log(err); //失败了!
})
const pro = new Promise(function(resolve,reject){throw new Error('test');
})
pro.catch(function(err){console.log(err); //Error: test
})
const promise = new Promise(function(resolve, reject) {try {throw new Error('test');} catch(e) {reject(e);}
});
promise.catch(function(error) {console.log(error);
});

方法:

1、resolve() 能将现有的任何对象转换成promise对象

let p = Promise.resolve('foo');
let p1 = new Promise(resolve => resolve('foo'));
console.log(p);
console.log(p1);

 2、reject() 同resolve()方法

3、all() 用于将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.all([p1, p2, p3]);

 1)p1、p2、p3都是Promise实例,如果不是,会先调用Promise.resolve()方法,将参数转为Promise实例,再进一步处理。参数可以不是数组,但必须具有Iterator接口,且返回的每个成员都是Promise实例。

2)只有三个参数p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,三参的返回值组成一个数组,传递给p的回调函数。

3)三参中只要有一个rejected,p的状态就是rejected,此时第一个被reject的实力的返回值传递给p的回调函数。

4)多应用与游戏霍素材比较多时,等待图片、falsh、静态资源文件都加载完成,才进行页面的初始化。

4、race() 给某个异步请求设置超时时间,并且在超时后执行相应的操作

function requestImg(imgSrc){return new Promise((resolve,reject)=>{const img = new Image();img.onload = function(){resolve(img);}img.src = imgSrc;})
}
function timeout(){return new Promise((resolve,reject)=>{setTimeout(()=>{reject(new Error('图片请求超时'));},3000)})
}
Promise.race([requestImg('img.png'),timeout()]).then(data=>{console.log(data);document.body.appendChild(data);
}).catch(err=>{console.log(err); //Error: 图片请求超时
})

5、finally() 用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。

2.10 Proxy对象

一、介绍

        用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。

        在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。

二、方法

1、get() 用于拦截某个属性的读取操作

var proxy = new Prosy({},{// target - 目标对象; propKey - 属性名;proxy实例本身,可选get:function(target,propKey,[proxy]){}
});

2、set() 用来拦截某个属性的赋值操作,接收四个参数:目标对象、属性名、属性值和proxy实例本身,最后一个参数可选。 

2.11 async的用法

一、async 异步操作

        作用:使得异步操作更加方便。

        基本操作 async 返回一个Promise对象  

        async是Genterator的一个语法糖

async function f(){// await不能单独使用,必须要在async中// return await 'hello async';let s = await 'hello async';let data = await s.split('');return data;
}   
// 如果async函数中有多个await 那么then函数会等待所有的await指令执行完的结果才去执行
f().then(v=>console.log(v)).catch(e=>console.log(e));
// ['h', 'e', 'l', 'l', 'o', ' ', 'a', 's', 'y', 'n', 'c']
async function f2(){// throw new Error('出错了');await Promise.reject('出错了');await Promise.resolve('hello');
}
// 只要有一个await命令进入reject就不会继续执行
f2().then(v=>console.log(v)).catch(e=>console.log(e)); // 出错了

 如果想要继续执行,修改代码如下:

async function f2(){// throw new Error('出错了');try {await Promise.reject('出错了');} catch (error) {}return await Promise.resolve('hello');
}
// 只要有一个await命令进入reject就不会继续执行
f2().then(v=>console.log(v)).catch(e=>console.log(e)); // hello

2.22 类class

        通过class关键字,可以定义类,是一个语法糖。

class Person{// 实例化的时候会立即被调用constructor(name,age){this.name = name;this.age = age;}// sayName(){//     return this.name;// }// sayAge(){//     return this.age;// }}
// 通过Object.assign()方法一次性向类中添加多个方法
Object.assign(Person.prototype,{sayName(){return this.name;},sayAge(){return this.age;}
})
let p1 = new Person('张三',20);
console.log(p1);
console.log(p1.sayName()); // 张三
console.log(p1.sayAge()); // 20

 类的继承

// 使用关键字extends
class Animal{constructor(name,age){this.name = name;this.age = age;}sayName(){return this.name;}sayAge(){return this.age;}
}
class Dog extends Animal{constructor(name,age,color){super(name,age); // 相当于Animal.call(this,name,age);this.color = color;}// 子类自己的方法sayColor(){return `${this.name},${this.age}个月,颜色是${this.color}`;}// 重写父类的方法sayName(){return this.name + super.sayAge() + this.color;}
}
let dog = new Dog('杜宾',12,'black');
console.log(dog); //{name: '杜宾', age: 12, color: 'black'}
console.log(dog.sayName()); // 杜宾
console.log(dog.sayColor()); //杜宾,12个月,颜色是black
console.log(dog.sayName()); //杜宾12black

2.23 模块化实现

        ES6 module 两个命令构成:export 和 import

        export 用于规定模块的对外接口,import用于输入其他模块提供的接口

        一个模块就是一个独立的文件

index.js

export const name = '张三';
export const age = 18;
// 函数抛出在函数前面增加export
export function sayName(){return 'my name is 哈哈哈';
}
// 或抛出一个对象
function sayAge(){return 19;
}
export {sayAge}
class Person{constructor(){}sayColor(){console.log("red");}
}
export default Person;

1.html

<script type="module">
import Person,{name,age,sayName,sayAge} from './index.js';
console.log(name,age,sayName(),sayAge()); // 张三 18 my name is 哈哈哈 19
const p = new Person();
p.sayColor(); //red
</script>

路漫漫其修远兮,吾将上下而求索!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/22577.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

将媒体公司资产迁移到 Amazon S3 的技术方案

随着媒体公司的发展&#xff0c;他们在仓库中积累了大量的旧磁带和未数字化的视频。这些资产可能很有价值&#xff0c;但以目前的形式很难访问和货币化。此外&#xff0c;将这些资产存储在仓库中既有风险又昂贵。 媒体企业可以通过将其资产迁移到云存储来解决这些问题&#xf…

i.MX6ULL(十五) 根文件系统

Linux“三巨头”已经完成了 2 个了&#xff0c;就剩最后一个 rootfs( 根文件系统 ) 了&#xff0c;本章我们就来学 习一下根文件系统的组成以及如何构建根文件系统。这是 Linux 移植的最后一步&#xff0c;根文件系统 构建好以后就意味着我们已经拥有了一个完整的、可以运…

Android13 编译错误汇总

1. error: New setting keys are not allowed 一版是在Settings中添加了新的字段导致的 解决&#xff1a; 在你的字段上面加上SuppressLint("NoSettingsProvider") 继续编译应该会出现 按照提示 make api-stubs-docs-non-updatable-update-current-api 然后再…

Java反射与“整活--(IOC容器)”

文章目录 前言反射什么是反射基本操作获取类对象获取类属性获取类方法方法的执行对构造方法的操作 注解定义获取注解 整活&#xff08;IOC容器&#xff09;项目结构IOC/DI流程ApplicationContextBeanDefinitionReaderBeanDefinitionBeanWrappergetBean&#xff08;&#xff09;…

【C++顺序容器】forward_list的成员函数和非成员函数

目录 forward_list 1. forward_list的成员函数 1.1 构造、析构和赋值运算符重载 1.1.1 构造函数 1.1.2 析构函数 1.1.3 赋值运算符重载 1.2 迭代器 1.3 容量 1.4 元素访问 1.4.1 遍历方法 1.5 修改器 1.6 操作 1.7 观察者 2. forward_list的非成员函数 forward_l…

3.SpringBoot 返回Html界面

1.添加依赖spring-boot-starter-web <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>2.创建Html界面 在Resources/static 文件夹下面建立对应的html&#xff0c…

实验:如何在YOLO8中添加PnP算法来实现Head Pose Estimation

目录 前言一、步骤二、PnP估计Head Pose&#xff0c;并显示1.引入库2.结果展示 总结 前言 YOLO&#xff18;的集成度比较高&#xff0c;如何在简洁的代码中加入Head Pose的东西&#xff0c;不是一件简单的事情&#xff0e;这里介绍如何插入PnP算法实现头部姿态估计的代码&…

Linux学习之vim在光标所在处写入内容,保存退出

vim insertTest使用vim打开一个叫做insertTest新文件。 输入命令之后&#xff0c;按下Enter&#xff08;回车键&#xff09;&#xff0c;就可以进入下边的操作页面。 按i在当前光标位置处&#xff0c;就可以插入内容了。 接下来写入内容跟记事本里边是差不多的。 按一下…

python_day8_综合案例

综合案例&#xff0c;全球GDP排行榜 1、知识点补充&#xff1a;sort()方法 sort()方法&#xff1a; 列表.sort(key选择排序依据的函数,reverseTrue|False) my_list [[a, 33], [b, 55], [c, 11]]def choose_sort_key(element):return element[1] # 列表中每个元素传进来&am…

Office如何通过VSTO进行PPT插件开发?

文章目录 0.引言1.工具准备2.PPT外接程序创建和生成3.外接程序生成并使用 0.引言 VSTO&#xff08;Visual Studio Tools for Office &#xff09;是VBA的替代&#xff0c;是一套用于创建自定义Office应用程序的Visual Studio工具包。VSTO可以用Visual Basic 或者Visual C#扩展O…

(转载)从0开始学matlab(第11天)—关系运算符和逻辑运算符

选择结构的运算由一个表达式控制的&#xff0c;这个表达式的结果只有 true(1)和 false(0)。有两种形式的运算符可以在 MATLAB 中关系得到 true/false&#xff1a;关系运算符和逻辑运算符。跟 C 语言一样&#xff0c;MATLAB 没有布尔型和逻辑数据类型。MATLAB 把 0 值作为结果fa…

android JSBridge的加载时机问题

https://github.com/lzyzsd/JsBridge 也算是比较悠久和使用了。 可供参考的android和IOS&#xff0c;以及前端的使用 https://segmentfault.com/a/1190000018208609 遇到的问题&#xff1a; 比如&#xff1a; 从前端在加载WebView的时候&#xff0c;执行了某些动作&#xff0c…