杨公子 發表於 2019-7-6 14:07:00

javascript中undefined的本质

<h1 id="undefined本质">undefined本质</h1>
<h2 id="一列出7种数据类型面试可能问">一、列出7种数据类型(面试可能问)</h2>
<ol>
<li>Undefined</li>
<li>Null</li>
<li>Boolean</li>
<li>String</li>
<li>Number</li>
<li>Symbol</li>
<li>Object</li>
</ol>
<h2 id="二undefined本质">二、undefined本质</h2>
<p>undefined是window对象的一个<strong>属性</strong>,其类型是Undefined。</p>
<p><img src="https://img2018.cnblogs.com/blog/1697677/201907/1697677-20190706141224884-46681496.png" alt="" loading="lazy"></p>
<p>下面解释javascript中属性的本质,因为undefined是一个属性,了解undefine的本质要用到属性的本质。</p>
<h2 id="三属性本质">三、属性本质</h2>
<p><strong>对JavaScript来说,属性并非只是简单的名称和值,JavaScript用一组特征(attribute)来描述属性(property)。</strong></p>
<p>先来说第一类属性,<strong>数据属性</strong>。它比较接近于其它语言的属性概念。数据属性具有四个特征。</p>
<ul>
<li>value:就是属性的值。</li>
<li>writable:决定属性能否被赋值。</li>
<li>enumerable:决定for in能否枚举该属性。</li>
<li>configurable:决定该属性能否被删除或者改变特征值。</li>
</ul>
<blockquote>
<p>补充:第二类属性是<strong>访问器(getter/setter)属性</strong>,它也有四个特征。 (本文用不到,但可以和第一类属性放在一起记忆)</p>
<ul>
<li>getter:函数或undefined,在取属性值时被调用。</li>
<li>setter:函数或undefined,在设置属性值时被调用。</li>
<li>enumerable:决定for in能否枚举该属性。</li>
<li>configurable:决定该属性能否被删除或者改变特征值。</li>
</ul>
</blockquote>
<p>我们通常用于定义属性的代码会产生数据属性,其中的writable、enumerable、configurable都默认为true。我们可以使用内置函数 Object.getOwnPropertyDescripter来查看,如以下代码所示:</p>
<pre><code class="language-js">const print = console.log
const o = {a: 1}
o.b = 2
// a和b均为数据属性
const aa = Object.getOwnPropertyDescriptor(o, 'a')
// {value: 1, writable: true, enumerable: true, configurable: true}
const bb = Object.getOwnPropertyDescriptor(o, 'b')
// {value: 2, writable: true, enumerable: true, configurable: true}
print('aa', aa)
print('bb', bb)
</code></pre>
<p><img src="https://img2018.cnblogs.com/blog/1697677/201907/1697677-20190706140247623-950652468.png" alt="" loading="lazy"></p>
<p>对window对象的undefined施加此函数:</p>
<p><img src="https://img2018.cnblogs.com/blog/1697677/201907/1697677-20190706140309062-419634533.png" alt="" loading="lazy"></p>
<p>由此看出undefined是window的第一类属性--数据属性,而且该属性不能能被赋值(writable=false),不能被for in枚举(enumerable=false),不能删除或改变特征值(configurable=false)。这也解释为什么给undefined重新赋值后其值却不改变:因为writable=false</p>
<p><img src="https://img2018.cnblogs.com/blog/1697677/201907/1697677-20190706140333726-1624288216.png" alt="" loading="lazy"></p>
<p>以及解释为什么不能重新用Object.defineProperty函数定义undefined:因为configurable=false</p>
<p><img src="https://img2018.cnblogs.com/blog/1697677/201907/1697677-20190706140404931-442383487.png" alt="" loading="lazy"></p>
<p>注:如果我们要想改变属性的特征,或者定义访问器属性,我们可以使用 Object.defineProperty</p>
<p><img src="https://img2018.cnblogs.com/blog/1697677/201907/1697677-20190706140429525-1984102326.png" alt="" loading="lazy"></p>
<h2 id="四undefined与null">四、Undefined与Null</h2>
<p>一个问题,为什么有的编程规范要求用void 0代替undefined?现在我们就分别来看一下。</p>
<p><img src="https://img2018.cnblogs.com/blog/1697677/201907/1697677-20190706140501380-297537279.png" alt="" loading="lazy"></p>
<p>Undefined 类型表示未定义,它的类型只有一个值,就是 undefined。任何变量在赋值前是 Undefined 类型、值为 undefined,一般我们可以用全局变量undefined(就是名为undefined的这个变量)来表达这个值,或者 <strong>void 运算来把任一一个表达式变成 undefined 值</strong>。</p>
<p>但是呢,因为JavaScript的代码undefined是一个变量,而并非是一个关键字,这是JavaScript语言公认的设计失误之一,所以,为了避免无意中被篡改,建议使用 void 0 来获取undefined值。</p>
<p>Undefined跟 null 有一定的表意差别,null表示的是:“定义了但是为空”。所以,在实际编程时,我们一般不会把变量赋值为 undefined,这样可以保证所有值为 undefined 的变量,都是从未赋值的自然状态 。</p>
<p>Null 类型也只有一个值,就是 null,它的语义表示空值,与 undefined 不同,null 是 JavaScript 关键字,所以在任何代码中,你都可以放心用 null 关键字来获取 null 值。</p>
<h2 id="五总结">五、总结</h2>
<p>undefined是window对象的一个属性其类型是Undefined,属性不是简单的名值对,它还具有一组特征值(attribute)。通过Object.getOwnPropertyDescriptor函数可以得到这组特征值。通过Object.defineProperty函数可以添加一个自定义特征值的属性,在已有属性的特征值configurable为true的前提下也可以通过该函数修改已有属性的特征值。</p>
<p>补充:undefined在全局环境没法被赋值,在局部环境是可以被赋值的!</p>
<p><img src="https://img2018.cnblogs.com/blog/1697677/201907/1697677-20190708172858922-642736019.png" alt="" loading="lazy"></p><br><br>
来源:https://www.cnblogs.com/wen-k-s/p/11142564.html
頁: [1]
查看完整版本: javascript中undefined的本质