es6学习(二)

Set 和 Map 数据结构

1,Set:类似于数组,但是成员都是唯一的,可以用来去重

增加变量的方法: add,在set看来两个对象都是不相等的, delete(value)删除某个值 has(value)判断有没有某个值 clear(value)清除整个set对象

数组与set互相转换: const set = new Set(xxx数组)和[...xxxSet],数组还可以用Array.from()方法将set转为数组

set的遍历: keys() values() entries() forEach() ,由于set没有键值所以keys和values方法的返回值一样,这样entries方法返回的键值和值是一样的

2,WeakSet

weakset与set类似,只有两个区别,一个是weakset只能存放对象,另一个是WeakSet引用都是弱引用,假如对象只是在WeakSet中引用,那么垃圾回收机制将会自动回收此对象,所以它没有遍历方法,因为它的对象随时都可能消失

语法:const ws = new WeakSet();

3,Map

题外话: forEach遍历对象(Obj.forEach(([key, value]) => {}))

构造函数: 任何具有Iterator 接口、且每个成员都是一个双元素的数组结构都可以构成一个Map对象

属性与方法: size(成员数量),set(新增成员),get(用key获键值),has(判断key是否存在),delete(删除key),clear(清空成员)

数据结构的转换: [...Map](Map转为数组),new Map(Array)(数组转为Map)

4,WeakMap

WeakMap与Map的区别有两点,一是WeakMap只接受对象作为键,其次,WeakMap的键名所指向的对象,不计入垃圾回收机制。

Proxy 

1,概述

Proxy用于修改某些默认操作的默认行为,可以理解成在目标对象之前架设一层拦截,外界在访问该对象时,都必须经过这层拦截

var obj = new Proxy({}, {
  get: function (target, key, receiver) {
    console.log(`getting ${key}!`);
    return Reflect.get(target, key, receiver);
  },
  set: function (target, key, value, receiver) {
    console.log(`setting ${key}!`);
    return Reflect.set(target, key, value, receiver);
  }
});

注: 要使得Proxy起作用,必须针对Proxy实例(上例是proxy对象)进行操作,而不是针对目标对象(上例是空对象)进行操作,如果handle没有设置任何拦截,那就等同于直接通向原对象。

var target = {};
var handler = {};
var proxy = new Proxy(target, handler);
proxy.a = 'b';
target.a // "b"

2,Proxy的方法

get:拦截属性的读取操作,三个参数,依次是目标对象(必选), 属性名(必选),proxy实力本身(非必选)

题外话: 匿名函数的写法有: var niminghanshu =  (function(x , y){})(这里传参) 

set:拦截属性的赋值操作,四个参数,依次是目标对象(必选), 属性名(必选),属性值(必选), proxy实力本身(非必选)

apply:拦截函数的调用、call和apply操作,三个操作,依次是目标对象、目标对象的上下文对象(this)、目标对象的参数数组

has:拦截Hasproperty操作,即判断对象是否具有某个属性时,这个方法会生效,两个参数,依次是目标对象、需查询的属性名

construct:拦截new命令,两个参数,依次是目标对象,参数对象,拦截必须返回一个对象,否则会报错

deleteProperty: 拦截delete操作,如果拦截返回错误或false,那么这个属性就不会删除

defineProperty: 拦截Object.defineProperty操作,如果拦截返回错误或false,那么这个属性就不会添加

var handler = {
  defineProperty (target, key, descriptor) {
    return false;
  }
};
var target = {};
var proxy = new Proxy(target, handler);
proxy.foo = 'bar' // 不会生效

getOwnPropertyDescriptor: getOwnPropertyDescriptor方法拦截Object.getOwnPropertyDescriptor(),返回一个属性描述对象或者undefined

getPrototypeOf: getPrototypeOf方法主要用来拦截获取对象原型

  • Object.prototype.__proto__
  • Object.prototype.isPrototypeOf()
  • Object.getPrototypeOf()
  • Reflect.getPrototypeOf()
  • instanceof

isExtensible: isExtensible方法拦截Object.isExtensible操作,注意,该方法只能返回布尔值,否则返回值会被自动转为布尔值这个方法有一个强限制,它的返回值必须与目标对象的isExtensible属性保持一致,否则就会抛出错误

var p = new Proxy({}, {
  isExtensible: function(target) {
    return false;
  }
});

Object.isExtensible(p) // 报错,因为它确实是true

ownKeys: ownKeys方法用来拦截对象自身属性的读取操作

  • Object.getOwnPropertyNames()
  • Object.getOwnPropertySymbols()
  • Object.keys()
  • for...in循环

注意,使用Object.keys方法时,有三类属性会被ownKeys方法自动过滤,不会返回

  • 目标对象上不存在的属性
  • 属性名为 Symbol 值
  • 不可遍历(enumerable)的属性

preventExtensions:拦截Object.preventExtensions()。该方法必须返回一个布尔值,否则会被自动转为布尔值

setPrototypeOf:拦截Object.setPrototypeOf方法,注意,该方法只能返回布尔值,否则会被自动转为布尔值。另外,如果目标对象不可扩展(extensible),setPrototypeOf方法不得改变目标对象的原型

3,Proxy.revocable

 Proxy.revocable方法返回一个可取消的 Proxy 实例

let target = {};
let handler = {};

let {proxy, revoke} = Proxy.revocable(target, handler); // 返回的是一个对象,对象的proxy属性就是proxy对象,revoke属性就是一个可以取消proxy函数

proxy.foo = 123;
proxy.foo // 123

revoke();
proxy.foo // TypeError: Revoked

Proxy.revocable的使用场景是,目标对象不允许直接访问,必须通过代理访问,一旦访问结束,就收回代理权,不允许再次访问 

4,this 问题

在 Proxy 代理的情况下,目标对象内部的this关键字会指向 Proxy 代理。

Reflect

1,概述

Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API,他的目的有:(1)将object对象一些明显属于语言内部的方法放到reflect上面,(2)修改object的一些方法结果让其变得合理,比如有的方法出错时会抛出异常,但是使用reflect的这个方法会返回Boolean数值,(3)让object操作都变成函数行为,有的操作之前是命令式的。比如delete xxx,现在改成Reflect.deleteProperty(obj, name),(4)reflect对象方法与proxy对象的方法都是一一对应的,这样在proxy函数中就算丢失this指向问题也可以用reflect来指向原对象,且proxy的拦截对reflect不起作用

Proxy(target, {
  set: function(target, name, value, receiver) {
    var success = Reflect.set(target,name, value, receiver); // 虽然被proxy拦截,但是利用reflect还是可以达到之前的默认效果
    if (success) {
      log('property ' + name + ' on ' + target + ' set to ' + value);
    }
    return success;
  }
});

 2,静态方法

reflect的静态方法与proxy的静态方法一致,只是功能有偏差

3,实例:使用 Proxy 实现观察者模式

利用proxy的拦截和reflect的代理默认方法,在拦截set的时候可以在完成默认事件之后完成自己的操作,这就起到了观察的作用

Promise 对象

1,Promise 的含义

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。promise对象的两个特点

(1)对象的状态不受外界影响,promise对象代表一个异步操作,有三种状态:pending(进行中),fulfilled(已成功),rejected(已失败)(2)一旦改变状态就不会改变

2,基本用法

const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

resolve函数将pending变成resolved并将参数带出去,reject函数将pending变成rejected并将参数带出去,promise实例生成以后可以用then方法指定resolved状态和rejected状态的回调函数。Promise 新建后就会立即执行,但是他的resolve方法和reject方法只会在本轮结束才执行。假如一个promise套另外的promise,那么只有里面的promise的状态完结之后外面的promise后续才会执行。注意:resolve和reject方法都不会结束promise的执行,假如在这两个方法之后还有其它语句,则还是会执行,所以一般是return resolve()这样的写法。

3,Promise.prototype.then

then是promise实例的状态改变时的回调函数,他的第一个参数是resolved状态的回调函数,为必选,第二个参数是rejected状态的回调函数,为非必选。then方法返回的是新promise实例,所以此写法为链式写法

4,Promise.prototype.catch

Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。

5,Promise.prototype.finally

finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。

6,Promise.all

Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。例:const p = Promise.all([p1, p2, p3]);

只有3个全变成resolved,总的才会变成resolved,只要有一个是rejected,总的就会是rejected。假如每个promise都有catch,那么总的promise的catch就不会捕获。

7,Promise.race

所有promise组成一个promise,谁先改变那么总的promise就随着它改变

8,Promise.resolve

作用:将现有对象转为 Promise 对象。参数的四种情况:(1)参数是promise实例,此方法将原封不动的返回此对象,(2)参数是一个thenable对象,比如:

let thenable = {
  then: function(resolve, reject) {
    resolve(42);
  }
};

那么此对象转成promise对象时会变成resolved状态,且立即调用then回调函数,(3)参数不是具有then方法的对象或根本就不是对象,调用此方法后会立即变成一个状态为resolved的promise对象且将此参数作为调用回调函数中的参数,(4)没有参数,直接立即变成一个状态为resolved的promise对象且调用回调函数

9,Promise.reject

与resolve方法用法相同,只是返回的是rejected状态的Promise实例,其次参数是thenable对象时reject方法返回的就是此thenable对象

10,Promise.try

有时为了让promise中的函数立即调用,promise.try()方法就是让promise中的回调函数立即执行,不会在本轮结束后才执行

Promise.try(database.users.get({id: userId}))
  .then(...)
  .catch(...)

Iterator 和 for...of 循环

ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。至于属性名Symbol.iterator,它是一个表达式,返回Symbol对象的iterator属性,这是一个预定义好的、类型为 Symbol 的特殊值,所以要放在方括号内,放在点号之后会被看做字符串

const obj = {
  [Symbol.iterator] : function () {
    return {
      next: function () {
        return {
          value: 1,
          done: true
        };
      }
    };
  }
};

原生具备 Iterator 接口的数据结构有:Array,Map,Set,String,TypedArray,函数的arguments对象,NodeList 

调用Iterator接口的场合:解构赋值、扩展运算符、yield*、数组的遍历

Iterator接口和Generator函数:利用generator的field声明来实现next方法

return和throw方法:用到return方法的时候是当循环报错或自动break时。

for...in和for...of的区别:for...in遍历数组的键名是数字,但是for...in循环是以字符串作为键名“0”、“1”、“2”,for...in循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键。

Generator 函数

1,简介

执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。形式上,Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态。yield表达式是暂停执行的标记,而next方法可以恢复执行

2,yield 表达式

yield表达式就是暂停标志。

遍历器对象的next方法的运行逻辑如下。

(1)遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。

(2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield表达式。

(3)如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。

(4)如果该函数没有return语句,则返回的对象的value属性值为undefined

另外,yield表达式如果用在另一个表达式之中,必须放在圆括号里面。

3,next 方法的参数

yield表达式本身没有返回值,或者说总是返回undefinednext方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。

4,Generator.prototype.throw

Generator 函数返回的遍历器对象,都有一个throw方法,可以在函数体外抛出错误,然后在 Generator 函数体内捕获。但是只能捕获一次。throw方法抛出的错误要被内部捕获,前提是必须至少执行过一次next方法。throw方法被捕获以后,会附带执行下一条yield表达式。也就是说,会附带执行一次next方法。另外,throw命令与g.throw方法是无关的,两者互不影响。

5,Generator.prototype.return

Generator 函数返回的遍历器对象,还有一个return方法,可以返回给定的值,并且终结遍历 Generator 函数。

6,yield* 表达式

一个generator函数中调用另一个generator函数的时候需要加上yield*前缀

async 函数

1,含义

async 函数是 Generator 函数的语法糖。async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await。

async函数对 Generator 函数的改进,体现在以下四点:

(1)内置执行器;async函数的执行,与普通函数一模一样,只要一行

(2)更好的语义:asyncawait,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果

(3)更广的适用性(4)返回值是 Promise

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园的建设目标是通过数据整合、全面共享,实现校园内教学、科研、管理、服务流程的数字化、信息化、智能化和多媒体化,以提高资源利用率和管理效率,确保校园安全。 智慧校园的建设思路包括构建统一支撑平台、建立完善管理体系、大数据辅助决策和建设校园智慧环境。通过云架构的数据中心与智慧的学习、办公环境,实现日常教学活动、资源建设情况、学业水平情况的全面统计和分析,为决策提供辅助。此外,智慧校园还涵盖了多媒体教学、智慧录播、电子图书馆、VR教室等多种教学模式,以及校园网络、智慧班牌、校园广播等教务管理功能,旨在提升教学品质和管理水平。 智慧校园的详细方案设计进一步细化了教学、教务、安防和运维等多个方面的应用。例如,在智慧教学领域,通过多媒体教学、智慧录播、电子图书馆等技术,实现教学资源的共享和教学模式的创新。在智慧教务方面,校园网络、考场监控、智慧班牌等系统为校园管理提供了便捷和高效。智慧安防系统包括视频监控、一键报警、阳光厨房等,确保校园安全。智慧运维则通过综合管理平台、设备管理、能效管理和资产管理,实现校园设施的智能化管理。 智慧校园的优势和价值体现在个性化互动的智慧教学、协同高效的校园管理、无处不在的校园学习、全面感知的校园环境和轻松便捷的校园生活等方面。通过智慧校园的建设,可以促进教育资源的均衡化,提高教育质量和管理效率,同时保障校园安全和提升师生的学习体验。 总之,智慧校园解决方案通过整合现代信息技术,如云计算、大数据、物联网和人工智能,为教育行业带来了革命性的变革。它不仅提高了教育的质量和效率,还为师生创造了一个更加安全、便捷和富有智慧的学习与生活环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值