陈良平 發表於 2025-5-30 10:21:00

Web前端入门第 61 问:JavaScript 各种对象定义与对象取值方法

<p>曾经有人说 JS 语言中<code>万物皆对象</code>,虽然这种说法不一定完全准确,但也有一定的道理。原因是 JS 的语法看起来所有的数据类型都像是一个对象,包括原始类型。</p>
<pre><code class="language-js">const a = 1.234;
console.log(a.toString());
console.log(a.valueOf());
console.log(a.toFixed(2));
console.log(Number.prototype); // 查看所有 Number 类型的原型链方法属性

const b = '前端路引';
console.log(b.length);
console.log(b.substring(2));
console.log(b.padEnd(10, '*')); // 后填充 * 字符
console.log(String.prototype); // 查看所有 String 类型的原型链方法属性

const c = true;
console.log(c.toString());
console.log(Boolean.prototype); // 查看所有 Boolean 类型的原型链方法属性
</code></pre>
<p>以上展示了 Number、String、Boolean 三种原始类型的方法。<code>a.xxx()</code> 这种写法就表示 <code>xxx</code> 是 a 的方法。</p>
<p>一般定义在对象上的 <code>函数</code> 都称之为 <code>对象方法</code>,使用语法: <code>xxx.yyy()</code>。对象除了方法还有 <code>对象属性</code>,使用语法: <code>xxx.yyy</code>。</p>
<p>方法和属性的区别是:方法是函数,属性是值。</p>
<p>举个例子:</p>
<pre><code class="language-js">const obj = {
name: '前端路引', // 对象属性
age: 1, // 对象属性
sayHi() { // 对象方法
    console.log(`我是${this.name},我今年${this.age}岁`);
}
}
</code></pre>
<p>以上是一个 JS 的对象字面量定义方式,除了最常用的对象字面量,还可以像 Array 一样,使用构造函数来定义对象,也可以使用 <code>Class</code> 自定义对象。</p>
<h2 id="对象定义">对象定义</h2>
<p>JS 的对象定义可比 数组 的花样多多了,下面来一一展示。</p>
<h3 id="对象字面量">对象字面量</h3>
<p>JS 的对象值与数组一样,无任何限制,可以是任意值,包括函数、数组、对象、undefined、null、NaN 等。</p>
<pre><code class="language-js">const dynamicKey = 'dynamicKey';
const fnKey = () =&gt; {};

const obj1 = {
name: '前端路引',
age: 1,
'favorite-color': 'blue', // 含特殊字符的键需用引号包裹
: 123, // Symbol 作为键
: 'value', // 使用动态变量作为属性名
: '使用函数作为键名称',
greet() { // 方法简写(ES6+)
    console.log('Hello!');
},
say: function () { // 函数
    console.log('Hi!');
}
};
</code></pre>
<h3 id="构造函数">构造函数</h3>
<p>虽然此方法使用较少,但这种方式也可以用来定义一个对象。以下代码与上面的对象字面量定义的对象一样:</p>
<pre><code class="language-js">const dynamicKey = 'dynamicKey';
const fnKey = () =&gt; {};

const obj2 = new Object();
obj2.name = '前端路引';
obj2.age = 1;
obj2['favorite-color'] = 'blue';
obj2 = 123;
obj2 = 'value';
obj2 = '使用函数作为键名称';
obj2.greet = function () {
console.log('Hello!');
}
obj2.say = function () {
console.log('Hi!');
}
</code></pre>
<h3 id="objectcreate">Object.create()</h3>
<p>使用对象的静态方法 <code>Object.create()</code> 来创建对象。</p>
<p>静态方法和对象原型链方法的区别是:静态方法属于对象本身,对象原型链上的方法属于对象实例。</p>
<p>看例子:</p>
<pre><code class="language-js">const obj3 = Object.create({ // 使用静态方法创建对象
name: '前端路引',
})
obj3.toString() // 调用原型链方法,也称为实例方法
</code></pre>
<p><code>Object.create</code> 多用于继承一个对象,扩展原有对象的功能:</p>
<pre><code class="language-js">const obj4 = {
name: '前端路引',
}
const obj5 = Object.create(obj4);
obj5.age = 1;
obj5['favorite-color'] = 'blue';
</code></pre>
<h3 id="自定义构造函数">自定义构造函数</h3>
<p>除了使用 JS 提供的内置构造函数,还可以自定义构造函数来创建一个对象。比如:</p>
<pre><code class="language-js">function WeChat () {
this.name = '前端路引';
this.age = 1;
this['favorite-color'] = 'blue';
}
const obj6 = new WeChat();
</code></pre>
<p><code>function</code> 关键字可不止用于函数定义,还能用来自定义构造函数,这是在 ES6 出现之前自定义类最常用的方式。</p>
<h3 id="class">Class</h3>
<p>为了消除语法歧义,ES6 引入了 <code>Class</code> 定义类,再通过 new 关键字创建实例对象,这种方式完全像是 function 的语法糖。</p>
<pre><code class="language-js">class WeChat {
constructor() {
    this.name = '前端路引';
    this.age = 1;
    this['favorite-color'] = 'blue';
}
say() {
    console.log('Hi!');
}
}
const obj7 = new WeChat();
</code></pre>

<h2 id="对象取值">对象取值</h2>
<p>对象的取值方法也多得眼花缭乱,下面一一展示。</p>
<h3 id="点语法">点语法</h3>
<p>常规属性可以使用 <code>.</code> 取值,比如:</p>
<pre><code class="language-js">const obj1 = {
name: '前端路引',
age: 1,
'favorite-color': 'blue',
say() {
    console.log('Hi!');
}
}
console.log(obj1.name); // 获取属性值
console.log(obj1.say()); // 调用方法
</code></pre>
<h3 id="方括号取值">方括号取值</h3>
<p><code>.</code> 语法有个问题,比如上面对象中 <code>favorite-color</code> 属性,如果直接使用 <code>obj1.favorite-color</code>,会报错,因为 <code>-</code> 会被当做减号处理,导致报错 <code>ReferenceError: color is not defined</code>。</p>
<p>这时候可以把对象当做数组来处理,使用方括号 <code>[]</code> 取值,比如:</p>
<pre><code class="language-js">const obj1 = {
name: '前端路引',
age: 1,
'favorite-color': 'blue',
say() {
    console.log('Hi!');
}
}
console.log(obj1['favorite-color']); // 获取属性值
console.log(obj1['say']()); // 调用方法
</code></pre>
<p>使用方括号取值时,如果属性名是动态的,可以使用变量来取值,比如:</p>
<pre><code class="language-js">const dynamicKey = 'dynamicKey';

const obj1 = {
: '前端路引',
}
console.log(obj1);
</code></pre>
<h3 id="解构赋值">解构赋值</h3>
<p>作为 ES6 引入的新特性,此写法如果不了解,那么代码可能都看不懂。</p>
<pre><code class="language-js">const obj1 = {
name: '前端路引',
age: 1,
}

const { name, age, up = '微信公众号' } = obj1;
console.log(name, age);
// 解构赋值,可以添加默认值,如果找不到属性,则使用默认值
console.log(up);
</code></pre>
<h3 id="object-静态方法">Object 静态方法</h3>
<p>Object 自身还提供了一些静态方法,用于获取数组的键值。</p>
<pre><code class="language-js">const obj1 = {
name: '前端路引',
age: 1,
}
const keys = Object.keys(obj1);    // 返回所有可枚举属性名数组
const values = Object.values(obj1);// 返回所有值数组
const entries = Object.entries(obj1); // 返回键值对数组
console.log(keys); // ['name', 'age']
console.log(values); // ['前端路引', 1]
console.log(entries); // 二维数组[['name', '前端路引'], ['age', 1]]
</code></pre>
<h3 id="getter--setter-方法">Getter / Setter 方法</h3>
<p>使用 <code>get</code> 方法,可以设置对象的计算属性,用于拦截对象的取值,比如:</p>
<pre><code class="language-js">const obj1 = {
firstName: '微信公众号:',
lastName: '前端路引',
get name() {
    return `${this.firstName}:${this.lastName}`; // 微信公众号::前端路引
},
set name(value) {
    = value.split(':');
}
}
console.log(obj1.name); // 微信公众号:前端路引
obj1.name = '前端路引:微信公众号';
console.log(obj1.name); // 前端路引:微信公众号
</code></pre>
<h3 id="原型链访问">原型链访问</h3>
<p>如果取的属性对象本身不存在,则会顺着原型链查找,直到找到为止,比如:</p>
<pre><code class="language-js">const obj1 = {
name: '前端路引',
age: 1,
}
console.log(obj1.toString()); // toString 方法不在对象本身,是 Object 原型链上的方法,也可以使用取值语法访问
</code></pre>
<h3 id="可选链">可选链</h3>
<p>ES2020 引入了可选链,用于解决对象取值时,如果属性不存在,会报错的问题,比如:</p>
<pre><code class="language-js">const obj1 = {
name: '前端路引',
age: 1,
}
// 如果直接取值,将会报错 TypeError: Cannot read properties of undefined (reading 'city')
console.log(obj1.address.city);
// 使用可选链,如果属性不存在,则返回 undefined,不会报错
console.log(obj1?.address?.city);
</code></pre>
<h2 id="写在最后">写在最后</h2>
<p>以上已包含绝大多数应用场景,但是也会有一些不太常用的写法未包含,比如 <code>Reflect.get(obj, 'a')</code>。作为入门条件,掌握以上内容已经完全够用。</p>


</div>
<div id="MySignature" role="contentinfo">
    <p>&nbsp;</p>
<p style="font-size: 18px;font-weight: bold;">文章首发于微信公众号【<span style="color:rgb(255, 71, 87)">前端路引</span>】,欢迎 <span style="color:#4ec259">微信扫一扫</span> 查看更多文章。</p>
<p>
<img style="max-width: 320px;" src="https://images.cnblogs.com/cnblogs_com/linx/2447020/o_250228035031_%E5%85%AC%E4%BC%97%E5%8F%B7%E4%BA%8C%E7%BB%B4%E7%A0%81.png"/>
</p>
<p>本文来自博客园,作者:前端路引,转载请注明原文链接:https://www.cnblogs.com/linx/p/18903865</p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/linx/p/18903865
頁: [1]
查看完整版本: Web前端入门第 61 问:JavaScript 各种对象定义与对象取值方法