Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduction to JavaScript(ES6) Proxy #16

Open
itstrive opened this issue Jun 13, 2019 · 2 comments
Open

Introduction to JavaScript(ES6) Proxy #16

itstrive opened this issue Jun 13, 2019 · 2 comments
Labels
article small article js About Js something

Comments

@itstrive
Copy link
Owner

参考资料: 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.

  • Proxy用法
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();
  • 我们扩展一个 fullName属性,以及如果没有属性了,提示信息换一下
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就是用来,增强(装饰或者叫赋能)一个对象的

  • 刚刚我们使用了 handler里面的 get,除此之外还有:

    • apply
    • construct
    • defineProperty
    • deleteProperty
    • get
    • getOwnPropertyDescriptor
    • getPrototypeOf
    • has
    • isExtensible
    • ownKeys
    • preventExtensions
    • set
    • setPrototypeOf

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

  • 在看下 handler里面的 set作用

我们都知道,一个人的年龄,肯定是整数,而且不能小于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; //抛出一个错误
  • Proxy 这个功能其实非常有想象力,后续浏览器也会重点优化更新此API,其他能想到的案例应用:

    • 保护对象的某个属性,比如ID不能删除 (使用: deleteProperty)
    • 跟踪属性的访问,比如扩展、验证(使用: get, set)
    • 数据绑定 (使用: set), Vue3.0重构使用就是它
    • 等等等..., 大家有好的用法,使用案例,欢迎留言
@itstrive itstrive added the article small article label Jun 13, 2019
@itstrive
Copy link
Owner Author

itstrive commented Jun 13, 2019

使用 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
Copy link
Owner Author

使用 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);

@itstrive itstrive added the js About Js something label Jun 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
article small article js About Js something
Projects
None yet
Development

No branches or pull requests

1 participant