1.proxy
Proxy对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如:属性查找、赋值、枚举、函数调用等)。
let obj = {
id:"0924",
name:"jerry",
phone:"18845612378",
birth:"1989-10-04"
}
let objProxy = new Proxy(obj,{
get:function(target,key){
switch (key) {
case 'phone':
//把中间的四位换成****
return target[key].substring(0,3) + "****" + target[key].substring(7);
break;
case 'birth':
//把1989替换成1999
return target[key].replace("1989","1999");
default:
return target[key];
break;
}
},
set:function(target,key,value){
if(key === "id"){
//如果要修改的属性是id,那么值就不变
return target[key];
}else{
//如果修改的是其他的属性,那么值就是修改后的
return target[key] = value;
}
},
//查找属性是否在对象中
has:function(target,key){
if(key in target){
//能查到就输出
console.log(`${key}:`,target[key]);
return true;
}else{
//查不到
console.log("查无此属性");
return false;
}
},
ownKeys(target){
return Object.keys(target).filter(function(item){
return item !== "id" && item.indexOf("_") !== 0
})
}
})
console.log(objProxy);
console.log(objProxy.name,objProxy.phone,objProxy.birth);
objProxy.id = "0725";
objProxy.name = "tom";
console.log(objProxy.id,objProxy.name);
console.log("sex" in objProxy);
console.log("name" in objProxy);
console.log(delete objProxy["_private"]);
console.log(Object.keys(objProxy));
输出的objProxy是代理之前的,只有在输出值的时候才会进到get方法。
2.reflect
操作对象和属性的另外一种方式,推荐使用reflect方式,这样操作更加直观。
let obj = {
name:"tom",
gender:"male",
hobbies:"swimming"
}
console.log(Reflect.get(obj,"gender"));
Reflect.set(obj,"name","jerry");
console.log(obj.name);
console.log(Reflect.has(obj,"hobbies"));
3.利用proxy,reflect模拟双向数据绑定
html页面
<h1>请输入文字:<span id="text"></span></h1>
<input type="text">
//获取元素
const input = document.querySelector("input");
const text = document.querySelector("#text");
//初始化对象
const obj = {};
//代理选项
const handler = {
get:function(target,key){
return Reflect.get(target,key);
},
set:function(target,key,value){
if(key === "text"){
//先判断输入框里的和显示出的文字是不是相同,提高效率
input.value === value ? input.value : value;
text.innerHTML = value;
}
return Reflect.set(target,key,value);
}
}
let objProxy = new Proxy(obj,handler);
//给input添加绑定事件
input.addEventListener("keyup",function(event){
objProxy.text = event.target.value;
})
objProxy.text = "123456";
4.函数的扩展
默认参数
{
function es5Fn(x,y){
y = y || "world";
return x + y;
}
console.log(es5Fn("hello",""));
}
{
function es6Fn(x,y="world"){
return x + y;
}
console.log(es6Fn("hello"));
}
reset(函数中形参以外剩余的参数,如果函数中没有其他形参,reset代表所有传入的参数,以数组的方式进行存储。)
function add(x,...reset){
console.log(reset);
}
add(1,2,3,4,5);
利用reset求传进来的所有数的和。
var num = 0;
function add(...reset){
for(var i = 0; i < reset.length; i++){
num += reset[i];
}
console.log(num);
}
add(1,2,3,4,5);
5.尾调用
在函数调用后返回另一个函数的调用,这称之为尾调用,如果后面有其他任何运算都不是尾调用。作用是提高递归的性能。
function fn2(){
console.log("尾调用");
}
function fn1(){
return fn2();
}
fn1();
6.箭头函数
声明函数
const arrow=(x)=>{
return x * 2;
}
console.log(arrow(123));
简写:如果参数列表只有一个可以省略小括号,如果函数体中只有一句代码可以省略大括号,如果这句代码作为函数的返回值,可以省略return关键字
const arrow= x => x * 2;
console.log(arrow(123));
const obj = {
name:"jerry",
hobby:"cherry"
}
window.setTimeout(function(){
console.log(this);
console.log(this.hobby);
},1000)
this指向的是window,window并没有age。
const obj = {
name: "jerry",
hobby: "cherry",
sum() {
window.setTimeout(() => {
console.log(this);
console.log(this.hobby);
}, 1000)
}
}
obj.sum()
箭头函数是没有自己的this的。
在js中什么时候用箭头函数?
Object.method(),调用某一个方法用普通函数,其他情况下用箭头函数。