itstrive / striveCode

some demo and js Knowledge points records :cn: :cloud: :snowflake:
108 stars 83 forks source link

Introduction to JavaScript(ES6) Proxy #16

Open itstrive opened 5 years ago

itstrive commented 5 years ago

参考资料: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy ES6视频资料: https://ke.qq.com/course/274758?taid=1770527253606726

认识一下 ES6中的 Proxy

这里简单介绍下,record一下,因为此API功能及其强大,后面慢慢记录.

这个也还称元编程,有点意思,什么是元编程,看下维基百科的解释: Metaprogramming is a programming technique in which computer programs have the ability to treat other programs as their data.

let p = new Proxy(target, handler);

target: 需要proxy的对象
handler: 给proxy对象进行赋能的一个对象

注意: 这两个都是object(json)
const doctor = {
    firstName:'Strive',
    lastName:'xiao'
}

console.group('doctor');
    console.log(doctor.firstName); //Strive
    console.log(doctor.lastName); //xiao
    console.log(doctor.org); //undefined
    console.log(doctor.fullName); //undefined
console.groupEnd();
let handler = {
    get:function(target, fieldName){
        if(fieldName == 'fullName'){ //如果访问的是 fullName
            return `${target.firstName} ${target.lastName}`;
        }
        return fieldName in target? target[fieldName]:`找不到属性: ${fieldName}`
    }
}

let p = new Proxy(doctor, handler);

console.group('doctor');
    console.log(p.firstName); //Strive
    console.log(p.lastName); //xiao
    console.log(p.org); //找不到属性: org
    console.log(p.fullName); //Strive xiao
console.groupEnd();

以上的handler,做了两件事,添加了一个 fullName属性,并且加了一个友好的提示语

小结: 大家有没有发现,其实Proxy就是用来,增强(装饰或者叫赋能)一个对象的

更详细的,大家可以看: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

我们都知道,一个人的年龄,肯定是整数,而且不能小于0,但是平时咱们设置,属性,设置什么就是什么

let p = {}

p.age = '我是年龄'; //这样其实有问题

或者

p.age = -10; //年龄不能小于0的,但是咱么之前没法友好的提示,或者判断,现在可以用Proxy
const handler = { //这个名字可以自己命名的
    set: function(obj, prop, value){
        if(prop == 'age'){
            if(!Number.isInteger(value)){
                throw new TypeError('年龄必须是整数');
            }
            if(value < 0){
                throw new TypeError('年龄需要大于0岁')
            }
        }
    }
}

let p = new Proxy(person, handler);

p.age = '我是年龄'; //抛出一个错误: 年龄必须是整数
p.age = -10; //抛出一个错误
itstrive commented 5 years ago

使用 set的小例子:

let user = {
    firstName: 'Strive',
    lastName: 'Chen'
};

user.age = 25;

console.group('User');
    console.log(user.firstName);
    console.log(user.lastName);
    console.log(user.age);
console.groupEnd();

user.age = '随便一些东西'
console.log(user.age);

user.age = -100
console.log(user.age);

// 这里的功能有点类似验证,所以取名 validator
const validator = {
    set: function(obj, prop, value) {
        if (prop === 'age') {
            if(!Number.isInteger(value)) {
                throw new TypeError('年龄必须为整数,请正确设置');
            }
            if(value < 0) {
                throw new TypeError('别闹,年龄必须大于0');
            }
        }
    }
};

// 创建一个Proxy
let p = new Proxy(user, validator);
p.age = '随便试试';

// 上面注释了,在看看
p.age = -1
itstrive commented 5 years ago

使用 deleteProperty 小例子

大多数情况,有些对象身上的属性,我们不希望删除的


let department = {
    id: '001',
    name: 'Strive',
    sex: 'women'
}

console.group('Department');
    console.log(department.id);
    console.log(department.name);
    console.log(department.manager);
console.groupEnd();

// delete department.id;
// console.log(department);

const deleteProxy = {
    deleteProperty: function(target, fieldName) {
        if(fieldName === 'id') return false;

        delete target[fieldName];
        return true;
    }
}

let p = new Proxy(department, deleteProxy);

delete p.id;
console.log(department);