1.Proxy代理
1 proxy的实现,get方法
let person = {
name: '张三'
};
let pro = new Proxy(person, {
get: function(target, property) {
console.log(target); //{name: "张三"}
console.log(property); //name
return '李四';
}
});
console.log(pro.name); //李四
new Proxy()生成一个Proxy实例,在Proxy构造函数中,第一个参数是源对象,第二个参数是一个对象,里面有一个get方法,get方法里面懂得匿名函数中传递的参数一个是target,代表的是源对象,property对象的是原对象对应的属性。这里Proxy的作用,将一个对象交给Proxy代理,然后通过编写处理函数来拦截目标对象的操作。person对象的name属性值不想被别人知道是”张三“,就设置了一个代理,让别人读取的时候,只获取到‘李四’。
let person = {
name: '张三',
age: 12
};
let pro = new Proxy(person, {
get: function(target, property) {
console.log(target); //{name: "张三"}
console.log(property); //name或者age,当打印pro.name的时候,property为name,当打印pro.age的时候,property为age
return '李四';
}
});
console.log(pro.name);
console.log(pro.age);
2.set方法
用于拦截对象的写操作
let bankAccount = {
RMB: 122,
dollar: 0
};
let banker = new Proxy(bankAccount, {
get: function(target, property) {
if (target[property] > 0) {
return target[property]
} else {
return '余额不足';
}
},
set: function(target, property, value) {
if (!Number.isInteger(value)) {
return '请输入正确格式'
} else {
target[property] = value;
}
}
})
console.log(banker.RMB); //122
console.log(banker.dollar); //余额不足
banker.dollar = '五百';
console.log(banker.dollar); //余额不足
banker.dollar = 500;
console.log(banker.dollar); //500
注意此方法里面打印的是代理函数,而不是原来的函数;
3.ownKeys方法:拦截操作,拦截过滤Object.ownKeys()对象的属性遍历,不能遍历出属性了。
let person = {
name: '张三',
age: 23,
height: 180
};
let proxy = new Proxy(person, {
ownKeys: function(target) {
return ['name', 'age']
}
});
console.log(Object.keys(person)); //["name", "age", "height"]
console.log(Object.keys(proxy)); // ["name", "age"]
console.log(person.height); //180 虽然被拦截,但是依旧还可以打印出来拦截的属性
4.has方法 has()拦截操作:拦截key in object的操作,结果会返回一个布尔值;
let person = {
name: '张三',
age: 23
};
let proxy = new Proxy(person, {
has: function(target, property) {
if (target[property] === undefined) {
return false
} else {
return true;
}
}
})
console.log('name' in proxy); //true
console.log('age' in proxy); //true
console.log('weight' in proxy);//false
let person = {
name: '张三',
age: 23
};
let proxy = new Proxy(person, {
// has: function(target, property) {
// if (target[property] === undefined) {
// return false
// } else {
// return true;
// }
// }
})
console.log('name' in proxy); //true
console.log('age' in proxy); //true
console.log('weight' in proxy); //false
注释掉has()方法,仍然返回true或者false,has()是代理函数内置的一个方法;
5.apply方法 除了对象类型的变量可以被代理,函数也可以被代理,如果被代理的变量是一个函数,那么还会支持一个拦截程序:apply调用;
let fn1 = function() {
alert('河北科技大学');
}
let proxy = new Proxy(fn1, {
apply: function() {
alert('河北师范大学');
}
})
proxy(); //弹出河北师范大学
6. proxy.revocable方法
如果创建了代理之后想要取消的话,可以用Proxy.revocable()函数来实现,它会返回一个对象,对象中含有一个proxy属性,
它就是Proxy的代理实例对象,还有一个revoke属性,它是一个方法,用于取消代理。
let person = {
name: '张三',
age: 12
};
let handle = {
get: function(target, property) {
return '李四';
}
}
let object = Proxy.revocable(person, handle);
console.log(object);
console.log(object.proxy.name); //李四
console.log(object.proxy.age); //李四
object.revoke();
console.log(object.proxy.name); //报错,代理被取消
7. for...of的使用
for...of是一种用于变量数据结构的方法,它可变量的对象包括数组,字符串,set和map结构等具有iterator接口的数据结构
遍历数组的几种方式
let arr = [1, 2, 3, 4, 5];
//遍历数组:方式1:for循环
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
//缺点:书写复杂,代码不够简洁
// 方式2:forEach()方法遍历
arr.forEach(function(value, index) {
console.log(value); //1 2 3 4 5
console.log(index); //0 1 2 3 4
})
//缺点:无法中断停止整个循环
//方式3:for...in循环
for (let value in arr) {
console.log(value); //0 1 2 3
}
// 缺点:返回的是索引,并且返回的类型是字符串类型
// 方式4:for...of循环
for (let value of arr) {
console.log(value); // 1 2 3 4 5
}
//for...of的优势:1.写法比for循环简洁;2.可以用break来终止整个循环,或者continue来跳出循环,继续执行后面的循环,
//结合keys()可以获取循环的索引,并且是数字类型。
//跳出循环
for (let value of arr) {
if (value == 3) {
break
}
console.log(value); // 1 2
}
//跳过当前循环
for (let value of arr) {
if (value == 3) {
continue
}
console.log(value); // 1 2 4 5
}
//结合arr.keys()得到索引
for (let index of arr.keys()) {
console.log(index); //0 1 2 3 4
}