阅读视图

发现新文章,点击刷新页面。

《JavaScript语言精粹》读书笔记之第3章:对象Object

小飞悟申明:小编的笔记只针对强者!!!

一、对象字面量 Object Literals

属性名可以是包括空字符串在内的任何字符串。在对象字面量中,如果属性名是一个合法的JavaScript标识符且不是保留字,则并不强制要求用引号括住属性名。所以用引号括住"first-name"是必需的,但是否括住first_name则是可选的。逗号用来分隔多个“名/值”对。

  1. 合法标识符 :
  • 如果属性名是合法的JavaScript标识符且不是保留字,可以不加引号。
- 例如:
const person = {
    firstName: 'John',
    lastName: 'Doe'
};


var flight = {
       airline: "Oceanic",
       number: 815,
       departure: {
          IATA: "SYD",
          time: "2004-09-22 14:55",
          city: "Sydney"
       },
  1. 非法标识符 :
  • 如果属性名包含特殊字符、空格或不是合法标识符,必须加引号。
- 例如
const person = {
    "first-name": 'John',
    "last name": 'Doe'
};

二、检索 Retrieval

要检索对象里包含的值,可以采用在[ ]后缀中括住一个字符串表达式的方式。如果字符串表达式是一个字符串字面量,而且它是一个合法的JavaScript标识符且不是保留字,那么也可以用.表示法代替。优先考虑使用.表示法,因为它更紧凑且可读性更好。

    stooge["first-name"]    // "Jerome"
    flight.departure.IATA   // "SYD"

运算符可以用来填充默认值:

    var middle = stooge["middle-name"] || "(none)";
    var status = flight.status || "unknown";

尝试从undefined的成员属性中取值将会导致TypeError异常。这时可以通过&&运算符来避免错误。

    flight.equipment                            // undefined
    flight.equipment.model                      // throw "TypeError"
    flight.equipment && flight.equipment.model  // undefined

三、引用 Reference

对象通过引用来传递。它们永远不会被复制:

理解对象引用

在JavaScript中,对象是通过引用来传递的,这意味着当将一个对象赋值给另一个变量时,两个变量实际上指向同一个对象。以下是对代码的详细解释:

  1. 对象引用 :
var x = stooge;
x.nickname = 'Curly';
var nick = stooge.nickname;
  • x 和 stooge 指向同一个对象,因此修改 x 的属性也会影响 stooge 。
  • nick 的值为 'Curly' ,因为 x 和 stooge 是同一个对象的引用。
  1. 多个对象引用 :
var a = {}, b = {}, c = {};
  • a 、 b 和 c 分别引用不同的空对象。
  1. 同一对象引用 :
a = b = c = {};
  • a 、 b 和 c 现在都引用同一个空对象。

四、原型 Prototype(简单介绍,后续会细讲)

每个对象都连接到一个原型对象,并且它可以从中继承属性。所有通过对象字面量创建的对象都连接到Object.prototype,它是JavaScript中的标配对象。 原型连接只有在检索值的时候才被用到。如果我们尝试去获取对象的某个属性值,但该对象没有此属性名,那么JavaScript会试着从原型对象中获取属性值。如果那个原型对象也没有该属性,那么再从它的原型中寻找,依此类推,直到该过程最后到达终点Object.prototype。如果想要的属性完全不存在于原型链中,那么结果就是undefined值。这个过程称为委托。

  • 这里仅是定义,后续会详细讲

刚开始有点难理解很正常,建议先看看blog.csdn.net/flyingpig20…

五、反射 Refelection

  • 用typeof操作符来确定属性类型很有帮助。
    typeof flight.number      // 'number'
    typeof flight.status      // 'string'
    typeof flight.arrival     // 'object'
    typeof flight.manifest    // 'undefined'
  • 在JavaScript中,原型链上的属性(如 toString 和 constructor )可能会产生值,但这些值通常是函数,可能并非我们需要的。以下是两种处理这些不需要的属性的方法:
    typeof flight.toString     // 'function'
    typeof flight.constructor  // 'function'
  1. 检查并丢弃函数值 :

    • 在程序中检查属性值是否为函数,如果是则丢弃。
    • 适用于需要动态获取对象信息且仅关注数据的场景。
  2. 使用 hasOwnProperty 方法 :

    • hasOwnProperty 方法用于检查对象是否拥有独有的属性(不检查原型链)。
    • 示例:
      flight.hasOwnProperty
      ('number');      // true
      flight.hasOwnProperty
      ('constructor'); // false
      
    • 适用于需要区分对象自身属性和继承属性的场景。 通过这两种方法,可以更精确地处理对象属性,避免不必要的函数值干扰。

六、枚举Enumeration

for in 语句的总结

for in 语句用于遍历对象的所有属性名,包括原型链中的属性。为了过滤掉不需要的属性,可以使用 hasOwnProperty 方法或 typeof 来排除函数。

示例 1:过滤函数属性

var name;
for (name in another_stooge) {
  if (typeof another_stooge[name] !== 'function') {
    document.writeln(name + ': ' + another_stooge[name]);
  }
}

示例 2:按特定顺序遍历属性

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[properties[i]]);
}

总结:for in 语句遍历对象属性时,属性顺序不确定。如果需要特定顺序,可以使用数组存储属性名,并通过 for 循环遍历。

七、删除Delte

删除对象属性的总结

delete 运算符用于删除对象的属性,但它不会影响原型链中的属性。如果删除的对象属性存在于原型链中,删除后原型链中的属性会“透现”出来。

示例

const stooge = {
  nickname: 'Curly'
};
const another_stooge = Object.create(stooge);
another_stooge.nickname = 'Moe';
console.log(another_stooge.nickname); // 'Moe'

delete another_stooge.nickname;
console.log(another_stooge.nickname); // 'Curly'(来自原型链)

解释

  1. another_stooge对象继承了stooge对象的nickname属性。
  2. 通过delete删除了another_stooge自身的nickname属性后,原型链中的nickname属性(值为'Curly')会显示出来。

通过这个示例,可以更好地理解delete运算符的作用及其对原型链的影响。

关键点

  1. 删除属性delete 删除对象自身的属性。
  2. 原型链delete 不会影响原型链中的属性。
  3. 透现属性:如果删除的属性存在于原型链中,删除后原型链中的属性会显示出来。

八、减少全局变量污染 Global Abatement

减少全局变量污染

在JavaScript中,全局变量(var)会削弱程序的灵活性,应尽量避免使用。最小化全局变量污染的一种方法是创建一个唯一的全局变量作为应用的容器,将所有全局性资源纳入该名称空间下。

示例

var MYAPP = {};
MYAPP.stooge = {
  "first-name": "Joe",
  "last-name": "Howard"
};
MYAPP.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"
  }
};


通过将全局资源集中在一个名称空间下,可以显著降低程序与其他应用程序、组件或类库之间的冲突风险,同时提高代码的可读性和维护性。但方法不止一种,ES6推出了let,const,在后面章节将会详细介绍,先看下区别:

let 、var 和const的区别

let和const 与var有什么区别

let和const 是es6的新语法,在函数预编译的时候会进行变量提升,这样在变量还没有赋值的时候就可以进行访问。

但是let和const不会,而且let和const遇到{}会形成块级作用域,并且let和const在声明之前是不能访问的,也不能访问

外部具有相同名字的变量因为会形成暂时性死区。这就是let、const和var的区别。

let和const的区别

它们两个的区别主要在let是声明变量,而const是声明常量的。

结语:

本文简单讲了下JavaScript中对象操作的核心概念,包括对象字面量、属性检索、原型链、反射、枚举、删除操作以及减少全局变量污染等关键点。现阶段建议读者继续深入了解下原型链和代理模式,后续小编还会奉上精彩好文!!!

❌