<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>DefineProperty 与 Proxy on Last Stand</title><link>https://amatsuzero.github.io/LastStand/tags/defineproperty-%E4%B8%8E-proxy/</link><description>Recent content in DefineProperty 与 Proxy on Last Stand</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Thu, 17 Jul 2025 00:00:00 +0800</lastBuildDate><atom:link href="https://amatsuzero.github.io/LastStand/tags/defineproperty-%E4%B8%8E-proxy/index.xml" rel="self" type="application/rss+xml"/><item><title>defineProperty 与 proxy</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/es6/es6-014/</link><pubDate>Wed, 02 Oct 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/es6/es6-014/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;我们或多或少都听过“数据绑定”这个词，“数据绑定”的关键在于监听数据的变化，可是对于这样一个对象：&lt;code&gt;var obj = {value: 1}&lt;/code&gt;，我们该怎么知道 obj 发生了改变呢？&lt;/p&gt;
&lt;h2 id="definepropety"&gt;definePropety&lt;/h2&gt;
&lt;p&gt;ES5 提供了 Object.defineProperty 方法，该方法可以在一个对象上定义一个新属性，或者修改一个对象的现有属性，并返回这个对象。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;语法&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Object.defineProperty(obj, prop, descriptor)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-makefile" data-lang="makefile"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; 要在其上定义属性的对象。
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;prop&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; 要定义或修改的属性的名称。
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;descriptor&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; 将被定义或修改的属性的描述符。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;举个例子：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Object.&lt;span style="color:#a6e22e"&gt;defineProperty&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;num&amp;#34;&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;value&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;writable&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;enumerable&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;configurable&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 对象 obj 拥有属性 num，值为 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;虽然我们可以直接添加属性和值，但是使用这种方式，我们能进行更多的配置。&lt;/p&gt;
&lt;p&gt;函数的第三个参数 descriptor 所表示的属性描述符有两种形式：&lt;strong&gt;数据描述符和存取描述符&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;两者均具有以下两种键值&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;configurable&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-arduino" data-lang="arduino"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;当且仅当该属性的&lt;/span&gt; configurable &lt;span style="color:#960050;background-color:#1e0010"&gt;为&lt;/span&gt; true &lt;span style="color:#960050;background-color:#1e0010"&gt;时，该属性描述符才能够被改变，也能够被删除。默认为&lt;/span&gt; false&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;enumerable&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-arduino" data-lang="arduino"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;当且仅当该属性的&lt;/span&gt; enumerable &lt;span style="color:#960050;background-color:#1e0010"&gt;为&lt;/span&gt; true &lt;span style="color:#960050;background-color:#1e0010"&gt;时，该属性才能够出现在对象的枚举属性中。默认为&lt;/span&gt; false&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;数据描述符同时具有以下可选键值&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;value&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;该属性对应的值&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;可以是任何有效的&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;JavaScript&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;值&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;（&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;数值&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;对象&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;函数等&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;）。&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;默认为&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;undefined&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;writable&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-arduino" data-lang="arduino"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;当且仅当该属性的&lt;/span&gt; writable &lt;span style="color:#960050;background-color:#1e0010"&gt;为&lt;/span&gt; true &lt;span style="color:#960050;background-color:#1e0010"&gt;时，该属性才能被赋值运算符改变。默认为&lt;/span&gt; false&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;存取描述符同时具有以下可选键值&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;get&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;一个给属性提供&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getter&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;的方法&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;如果没有&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getter&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;则为&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;undefined&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;该方法返回值被用作属性值&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;默认为&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;undefined&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;set&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;一个给属性提供&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;setter&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;的方法&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;如果没有&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;setter&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;则为&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;undefined&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;该方法将接受唯一参数&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;并将该参数的新值分配给该属性&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;默认为&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;undefined&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;值得注意的是：&lt;/p&gt;</description></item></channel></rss>