Skip to content

Introduction to JavaScript(ES6) Proxy #16

@itstrive

Description

@itstrive

参考资料: 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重构使用就是它
    • 等等等..., 大家有好的用法,使用案例,欢迎留言

Metadata

Metadata

Assignees

No one assigned

    Labels

    articlesmall articlejsAbout Js something

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions