Proxy
const obj1 = {
name: 'guaqiu5',
age: 20
}
let proxyObj = new Proxy(obj1, {
get: function(target, prop) {
console.log(target, prop);
return target[prop];
},
set: function(target, prop, value) {
console.log(target, prop, value);
target[prop] = value;
return target[prop];
}
})
//console.log(proxyObj.name);
//set 不能用key索引器来修改proxy代理的value 提示undefined
//proxyObj.age = 30;
//对比Object.defineProperty的优势
//proxy可监视更多的对象操作
let arr = [];
let arrProxy = new Proxy(arr, {
set: function(target, props, value) {
target[props] = value;
console.log('arr' + '' + props + 'has changed to' + value);
return true;//return true好像很有必要 否则报错
}
})
arrProxy.push(1);
//proxy更好的支持数组对象
//Object.defineProperty监视数组是重写了数组的方法、
//proxy是以非侵入式的方式监视数据的读写
\
Reflect
是一个静态类 只能调用类中的方法
proxy如果不给get和set方法 默认调用Reflect的get set方法.
价值:统一提供了一套用于操作对象的API
//Reflect 提供了一套标准的用于操作对象的api
const { log } = console;
const obj = {
name: "guaqiu5",
age: 20,
location: "jiangsu"
};
log(Reflect.has(obj, 'name')); //对象中是否存在某个key
log(Reflect.deleteProperty(obj, 'age')); //删除对象中的某个key
log(Reflect.ownKeys(obj)); //列出对象中的所有key
\
Promise
会有一篇详细介绍并手写
class类
//es6之前写类
function Student(name) {
this.name = name;
}
//这里不能用箭头函数,因为箭头的this是定义该函数时所在作用域指向的对象
//此时函数定义所在作用域为window
//而普通函数,谁调用就是谁
Student.prototype.say = function() {
console.log(this);
console.log(`hello i am ${this.name}`);
};
Student.prototype.bye = () => {
console.log(this);
}
//es6后
class Stu {
constructor(name) {
this.name = name;
}
//非静态方法 this指向该类里的实例。
say = () => {
console.log(this)
console.log(`hello i am ${this.name}`);
}
}
const s1 = new Student("杂鱼");
const s2 = new Stu("土鸡");
const s3 = new Stu("杂鸟");
s1.say();
s1.bye();
s2.say();
s3.say();
静态方法
类中用static关键字,注意this指向为该类。
继承
//extends 继承
class Person {
constructor(name) {
this.name = name;
}
say() {
console.log("hi i am " + this.name);
}
}
class Student extends Person {
constructor(name, number) {
super(name);
this.number = number;
}
say() {
super.say();
console.log("i am a student" + this.number);
}
}
const s1 = new Student("杂鱼", '12345');
s1.say();
Set
//Set es6新增数据结构
const s = new Set([1, 2, 4, 3]);
//可以链式add
s.add(7).add(9);
//遍历方式
s.forEach((e) => {
console.log(e);
})
//删除元素
s.delete(9);
//es6新特性 for of 遍历
for (e of s) {
console.log(e);
}
//s.size 输出set的大小
console.log(s.size);
//s.has() 是否有某个值
console.log(s.has(1));
//应用 数组去重
let arr = [1, 2, 2, 4, 4, 4, 9, 8]
const s2 = new Set(arr);
//set转换为数组可用Array.from 或者...操作符
arr = Array.from(s2);
let newArr = [...s2];
console.log(arr);
console.log(newArr);
symbol
略
for of循环
for each无法终止遍历,之前终止遍历需要使用some every
如何让自定义对象实现for of遍历?
实现lterable接口是实现for of的前提。
该对象的原型有一个Symbol.iterator对象,
该对象有一个next属性指向下一个对象。
每调用一次next,next指针会后移。
//迭代器iterator
let set = new Set(["name", "age", "sex", "hobby"])
const { log } = console
let iterator = set[Symbol.iterator]();
log(iterator);
log(iterator.next());
log(iterator.next());
log(iterator.next());
log(iterator.next());
log(iterator.next());
//迭代器iterator
//意义:对外实现统一遍历接口
const obj = {
name: ["杂鱼", "土鸡", "傻鸟"],
age: [1, 2, 3, 4],
sex: [0, 1],
//不用迭代器怎么写
each: function(callback) {
const all = [].concat(this.name, this.age, this.sex);
for (item of all) {
callback(item);
}
},
//用迭代器怎么写
[Symbol.iterator]: function() {
const all = [...this.name, ...this.age, ...this.sex];
let index = 0;
return {
next: function() {
return {
value: all[index],
done: index++ >= all.length ? true : false
}
}
}
}
}
// obj.each((item) => {
// console.log(item);
// })
for (item of obj) {
console.log(item);
}