JavaScript的Proxy对象详解

yizhihongxing

JavaScript的Proxy对象详解

什么是Proxy对象

Proxy 是 ES6 新增的语法,它允许你在外部控制对象和函数的访问行为。可以说,Proxy 是以对象为基础的 元编程 ,使得我们可以编写出更加可复用,更加通用的 Javascript 代码。

创建一个Proxy对象

可以使用 new 操作符来创建一个 Proxy 对象,其中第一个参数为需要代理的对象,第二个参数为代理行为的定义。

示例代码如下:

let proxy = new Proxy(target, handler);

在上面的代码中,target 指的是被代理的目标对象,handler 对象定义了代理行为的具体实现。

Proxy对象的方法

Proxy 对象会为被代理对象提供一些默认的方法,它们会影响到被代理对象的访问。

  1. get(target, propKey, receiver)

    该方法会在访问属性时被调用,接收三个参数,分别是对象本身,属性 key 值,以及 Proxy 对象本身。在该方法中,可以对属性的访问进行拦截和处理。

    下面是一个简单的示例:

    ```javascript
    let target = {
    name: 'Proxy'
    };

    let handler = {
    get: function(target, propKey) {
    if (propKey in target) {
    return target[propKey];
    } else {
    return Property ${propKey} does not exist.;
    }
    }
    };

    let proxy = new Proxy(target, handler);

    console.log(proxy.name); // Proxy
    console.log(proxy.age); // Property age does not exist.
    ```

    在上面的代码中,我们定义了一个 handler 对象,并在其中定义了 get 方法来对属性的访问进行拦截。当访问的属性存在时,我们将直接返回 target[propKey]。当属性不存在时,我们返回一个错误信息。

  2. set(target, propKey, value, receiver)

    该方法会在设置属性时被调用,接收四个参数,分别是对象本身,属性 key 值,打算设置的属性值,以及 Proxy 对象本身。在该方法中,可以对属性的设置进行拦截和处理。

    下面是一个简单的示例:

    ```javascript
    let target = {
    name: 'Proxy'
    };

    let handler = {
    set: function(target, propKey, value) {
    if (propKey === 'age') {
    if (typeof value !== 'number') {
    throw new TypeError('The age must be a number.');
    }
    }
    target[propKey] = value;
    }
    };

    let proxy = new Proxy(target, handler);

    proxy.age = 18; // ok
    proxy.age = '18'; // Error: The age must be a number.
    ```

    在上面的代码中,我们定义了一个 handler 对象,并在其中定义了 set 方法来对属性的设置进行拦截。当打算设置的属性为 'age' 时,我们检查其类型是否为 number。如果不是,我们抛出一个错误信息。如果是,我们则直接将值设置到 target[propKey] 中。

示例应用

劫持一个对象所有的 get 操作

默认情况下,访问一个 JavaScript 对象中不存在的属性会返回 undefined。但是在某些情况下,我们可能需要更加优雅的方式,而不是直接返回 undefined。这就是我们可以使用 Proxy 对象的 get 方法,劫持对象所有的 get 操作。

下面是一个实现:

let target = {
    name: 'Proxy'
};

let handler = {
    get: function(target, propKey) {
        return `The value of property ${propKey} is ${target[propKey]}.`;
    }
};

let proxy = new Proxy(target, handler);

console.log(proxy.name);    // The value of property name is Proxy.
console.log(proxy.age);     // The value of property age is undefined.

代码中,我们如下修改:

  1. 重写了 handler.get 方法,将属性访问劫持,并返回一个判断。
  2. target 为基础,利用 handler 创建 proxy

通过上面示例可以看出,当我们访问 proxy 对象中不存在的属性时,它会返回一个提示信息,并告知所查询的属性名。

阻止调用对象中的某个函数

Proxy 对象不仅可以拦截属性的访问,还可以拦截函数的调用。这在某些情况下可能非常有用。

下面是一个实现:

let obj = {
    add: function(a, b) {
        return a + b;
    },
    minus: function(a, b) {
        return a - b;
    }
};

let handler = {
    apply: function(target, thisArg, args) {
        if (target === obj.minus) {
            if (args[0] > args[1]) {
                return target.apply(thisArg, args);
            }
            else {
                throw new Error('Cannot execute the minus method, because the first parameter is less than the second parameter.');
            }
        } else {
            throw new Error('Cannot execute the add method.');
        }
    }
};

let proxy = new Proxy(obj, handler);

console.log(proxy.add(1, 2));                // Error: Cannot execute the add method.
console.log(proxy.minus(2, 1));              // 1
console.log(proxy.minus(1, 2));              // Error: Cannot execute the minus method, because the first parameter is less than the second parameter.

在该示例中,我们定义了一个 obj 对象,其中包含 addminus 两个函数。使用 new 操作符创建了 handler 对象,它覆盖了 apply 方法,从而拦截 obj 对象中所有函数的调用。

这里我们可以看到,当调用 add 方法时,handler.apply 方法会阻止它的执行并抛出一个错误。而当调用 minus 方法时,handler.apply 判断其传入的参数,只有在第一个参数大于第二个参数时才允许其执行,否则也会抛出一个错误。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript的Proxy对象详解 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • js 得到文件后缀(通过正则实现)

    要得到一个文件的后缀,可以通过以下步骤来实现: 步骤 1:获取完整文件名 首先,我们需要获取文件的完整文件名,可以通过以下方式来获取: let fileName = ‘example.txt’; 步骤 2:通过正则表达式获取文件后缀 我们可以使用正则表达式来获取文件的后缀,正则表达式的语法为: /\.[^.]+$/g 该正则表达式的含义为: /\. :匹配以…

    JavaScript 2023年5月27日
    00
  • vue-music关于Player播放器组件详解

    vue-music关于Player播放器组件详解 Vue-music是一款基于Vue.js的音乐WebApp,它的开源代码也被广泛使用于其他Vue项目中。其Player播放器组件是整个应用中最核心的组件之一,本文将对其进行详细的解析和介绍。 功能模块 Player播放器组件具有以下功能模块: 播放、暂停、上一曲、下一曲等基本音乐播放操作; 歌曲封面、歌词、进…

    JavaScript 2023年6月11日
    00
  • 图解JavaScript作用域链底层原理

    下面就为大家讲解一下“图解JavaScript作用域链底层原理”的完整攻略。 什么是作用域链? 作用域链指的是在 JavaScript 中,用于查找变量的一种机制。在 JavaScript 中,每个函数都有一个作用域链,它是由多个执行上下文(Execution Context)(如全局上下文、函数上下文等)的变量环境引用组成的链式结构。在查找变量时,Java…

    JavaScript 2023年6月10日
    00
  • 跨浏览器开发经验总结(四) 怎么写入剪贴板

    没问题。本文将帮助你学习如何使用JavaScript和HTML来实现向剪贴板中写入内容的功能。 HTML部分 使用HTML5中的<button>标签,以及一个带有id属性的<textarea>元素来写一个表单。 <button onclick="copyToClipboard()">Copy to cl…

    JavaScript 2023年6月11日
    00
  • Js中setTimeout()和setInterval() 何时被调用执行的用法

    当我们写JavaScript代码时,经常需要用到定时器来调用一些方法或者函数。其中,setTimeout()和setInterval()就是两个常用的方法。在此,我将向你详细讲解它们的用法及何时被调用执行。 setTimeout() setTimeout()方法用于在指定的时间后执行给定的代码。它的语法格式如下: setTimeout(function, d…

    JavaScript 2023年6月11日
    00
  • javascript 实现字符串反转的三种方法

    当我们需要对字符串进行操作时,有时候需要对字符串进行反转操作。下面我将介绍三种常见的JavaScript实现字符串反转的方法。 方法一:使用数组的reverse()方法 步骤如下: 将字符串转为数组 使用数组的reverse()方法进行反转 使用数组的join()方法将数组转化为字符串 示例代码如下: const str = ‘Hello World!’; …

    JavaScript 2023年5月28日
    00
  • Javascript标准DOM Range操作全集第3/3页

    首先,我们需要了解DOM Range是什么。DOM Range是一种表示文档中某个区域的对象。它可以用来选择某个范围内的文本、节点或元素,并进行相关操作。 接下来,我们来详细讲解Javascript标准DOM Range操作全集第3/3页的完整攻略。 一、创建Range并进行文本操作 我们可以通过如下代码创建一个Range: var range = docu…

    JavaScript 2023年6月10日
    00
  • vue webpack重写cookie路径的方法

    让我们来详细讲解“vue webpack重写cookie路径的方法”的完整攻略。 什么是cookie路径重写 cookie是一种在访问者计算机中存储数据的小型文本文件,它在Web应用程序中广为使用。默认情况下,如果没有指定cookie的路径,则 cookie被设置为页面当前路径。当你使用Vue和Webpack构建一个Web应用程序时,应用程序的路径可能不会在…

    JavaScript 2023年6月11日
    00
合作推广
合作推广
分享本页
返回顶部