根据《JavaScript语言精粹》了解JavaScript对象

12 阅读5分钟

JavaScript对象:

理解JavaScript对象,是理解JavaScript这门语言的关键一步。

作为JavaScript初学者,我最近深入阅读了《JavaScript语言精粹》第三章关于对象的章节。对象是这一切存在和发生的宇宙。所有的东西想要运转都要有对象

什么是对象?

在JavaScript中,几乎所有东西都是对象。

简单类型包括:数字、字符串、布尔值、nullundefined。其他所有值都是对象——数组是对象,函数是对象,正则表达式是对象,当然,对象自然也是对象。

对象是属性的容器,每个属性都有一个名字和一个值。属性名可以是任何字符串,属性值可以是除 undefined 之外的任何值。

1. 对象字面量

一个对象字面量就是包围在一对花括号中的零或多个“名/值对”

创建对象最简单的方式就是使用对象字面量

var person = {
  name: "张三",
  age: 25,
  job: "前端工程师"
};

注意:属性名是合法且非保留字,不需要“”,如果是连接符-连接的则不合法,必须括起来。例如"a-b",下画线_连接是合法的!

var person = {
  "first-name": "张",
  "last-name": "三"
};

属性的值可以从包括另一个对象字面量在内的任意表达式中获得。对象可以嵌套:

var flight = {
airline: "Oceanic"
number:815, 
departure: {
IATA"SYD"
time:"2004-09-22 14:55”
city:"Sydney"
},
arrival:{
IATA:"LAX"
time: "2004-09-23 10:42"
city: "Los Angeles"
}
};

2. 检索属性值

获取对象属性的值有两种方式: 要检索对象中包含的值,可以采用在【】后缀中括住一个字符串表达式的方式。 如果字符串表达式是一个常数,而且它是一个合法的 JavaScript 标识符而并非保留字,那么也可以用表示法代替。 优先考虑使用.表示法,因为它更紧凑且可读性更好。

// 点表示法(更常用)
person.name  // "张三"

// 括号表示法
person["name"]  // "张三"

如果尝试检索不存在的属性,会返回 undefined

person.salary  // undefined

可以使用 || 运算符设置默认值:

var salary = person.salary || "未知";  // "未知"

3. 更新属性值

通过赋值语句可以更新对象属性:

person.age = 26;  // 更新已有属性
person.city = "上海";  // 添加新属性

4. 对象引用

对象通过引用传递,而不是拷贝:

var obj1 = { value: 1 };
var obj2 = obj1;  // obj2和obj1引用同一个对象
obj2.value = 2;
console.log(obj1.value);  // 2,obj1也被修改了

5. 原型

每个JavaScript对象都连接到一个原型对象,并从中继承属性。 当你创建一个新对象时,你可以选择某个对象作为它的原型。JavaScript 提供的实现机制杂乱而复杂,但其实它可以被明显地简化。我们将给 Object增加一个 beget 方法。 这个beget 方法创建一个使用原对象作为其原型的新对象。

if (typeof Object.beget !== 'function') {
Object.beget = function (o){
var F  function (){};
F.prototype = o;
return new F();
};
}
var another_stooge - Object.beget(stooge) ;

原型链的查找机制:当访问对象属性时,如果对象自身没有该属性,JavaScript会沿着原型链向上查找。

6. 反射

使用 typeof 操作符可以检查属性类型:

typeof person.name  // "string"
typeof person.age   // "number"

有两个方法去处理这些不需要的属性。第一个是让你的程序检查并刷除函数值。 一般来说,做反射的目标是数据,因此你应该意识到一些值可能会是函数。 另一个方法是使用 hasOwnProperty 方法,如果对象拥有独有的属性,它将返回 true. hasOunProperty方法不会检查原型链。

person.hasOwnProperty("number")  // true
person.hasOwnProperty("construtor")  // false

7. 枚举属性

使用 for...in 循环可以遍历对象所有属性(包括原型链中的):

for (var prop in person) {
  console.log(prop + ": " + person[prop]);
}

属性名出现的顺序是不确定的,因此要对任何可能出现的顺序有所准备。如果你想要确保 属性以特定的顺序出现,最好的办法就是完全避免使用 for in语句,而是创建一个数组, 在其中以正确的顺序包含属性名:

var i;
var properties = [
'first-name',
'middle-name ',
'last-name',
'profession',
];
for (i =0: i < properties.length; i += 1){
document.writeln (properties[i] +':'+
another_stooge[pzopezties[1]]);
}

通过使用 for 而不是 for in,可以得到我们想要的属性,而不用担心可能发掘出原型链 中的属性,并且我们按正确的顺序取得了它们的值。

8. 删除属性

使用 delete 运算符可以删除对象属性:

delete person.job;  // 删除job属性

注意:delete 不会删除原型链中的属性。

9. 减少全局变量污染

全局变量是JavaScript中最糟糕的特性之一。 JavaScript 可以很随意地定义那些可保存所有应用资源的全局变量。 不幸的是,全局变批削弱了程序的灵活性,所以应该避免。 最小化使用全局变量的一个方法是在你的应用中只创建啡一一个全局变量:

var MYAPP =();

该变量此时变成了你的应用的容器:

MYAPP.stooge ={
"first-name":"Joe""last-name":"Howard"
};

MYAPP.flight ={
airline: "Oceanic", 
number: 815,
departure:{
IATA:"SYD"
time:"2026-01-25 14:55”,
city: "Sydney"
},
arrival:{
IATA:"LAXtime: "2026-01-25 10:42”
city: "Los Angeles"
}
};

只要把多个全局变量都整理在一个名称空间下,你将显著降低与其他应用程序、组件或类 库之间产生糟糕的相互影响的可能性。你的程序也会变得更容易阅读,因为很明显 MYAPP.stooge 指向的是顶层结构。在下一章中,我们将会看到使用闭包来进行信息隐藏的 方式,它是另一个有效减少全局污染的方法

这样做的好处:

  • 减少全局变量数量
  • 避免命名冲突
  • 代码结构更清晰

总结

JavaScript对象是这门语言的核心。理解对象字面量、属性访问、原型继承这些概念,是掌握JavaScript的关键。对象提供了灵活的数据结构,原型提供了强大的继承机制,而良好的编码习惯(如减少全局变量)能让你的代码更加健壮。

总而言之:在JavaScript中,对象不仅仅是数据的容器,更是构建复杂应用的基石。