你不知道的JavaScript(上卷):第三章:对象

2020-01-03  本文已影响0人  本一和他的朋友们

一:这一章到底在说什么?

详细介绍对象。

  1. 语法
  2. 类型
  3. 内容
    1. 可计算属性
    2. 属性和方法
    3. 数组
    4. 复制对象
    5. 属性描述符
    6. 不变性
    7. [Get]
    8. [Put]
    9. Getter和Setter
    10. 存在性
  4. 遍历

二:作者具体说了什么,怎么说的?

3.1:语法

创建对象的两种方式:声明形式和构造形式。

声明形式

Var myObject = {
    key: value,
    // ….
}

构造形式

Var myObj = new Object();
myObj.key = value

两种形式的区别

  1. 声明形式可以添加多个键/值对(一般也都是这种方式创建对象)
  2. 构造形式必须逐个添加属性

3.2: 类型

对象是JavaScript的基础,其中有一些对象子类型,被称为内置对象。如下:

  1. String
  2. Number
  3. Boolean
  4. Object
  5. Function
  6. Array
  7. Date
  8. RegExp
  9. Error
    这些内置对象很像其他语言中的type或class,但是实际上只是一些内置函数。这些内置函数可以当作构造函数来使用,从而构造出一个对应子类型的新对象。比如:
Var strObject = new String(“i am a stirng”)
Typeof strObject; // object

3.3: 内容

3.3.1:可计算属性名
可以在文字形式中使用[]包括一个表达式当作属性名
代码如下:

var preFix = “foo”;

var myObject = {
  [preFix + “bar”]: “hello”,
  [preFix + “baz”]: “world”
};

myObject[“foobar”]; // hello
myObject[“foobaz”]; // world

可计算属性命最常用的场景可能是es6的符号(Symbol) ,这是一种新的基础数据类型,包含一个不透明且无法预测的值。比如:

var mySymbol = {
  [Symbol.SomeName]: “hello world”
};          

3.3.2 属性与方法

3.3.3: 数组
数组其实也是对象的一种,你可以给数组添加属性,但是不推荐这么用。
比如:

var myArr = [“foo”, 3, “bar”]

myArr.baz = “baz”;
myArr.length; // 3
myArr.baz; // baz

3.3.4: 复制对象
会有深复制、浅复制的区别,同时JSON.toString方法。
3.3.5:属性表述符
对象属性对应的属性描述符。比如

var myObject = {
    a: 2
}

Object.defineProperty(myObject, “a”, {
    value: 2,
    writable: true, //是否可以修改属性的值
    configurable: true, // 是否可配置
    enumerable: true //是否出现在for…in等枚举中
})

3.3.6:不变性
举个例子:我不想让myArr.first的值发生变化,有哪几种方式?

myArr.first; // [1,2,3]
myArr.first.push(4); 
myArr.first; // [1,2,3,4]
  1. 对象常量:结合 writeable:false和configurable:false设置
  2. 禁止拓展:Object.preventExtensions(myArr.first)
  3. 密封:Object.seal(myArr.first); 该方法会创建一个密封的对象,这个方法实际上会在一个现有对象上调用Object.preventExtensions并把所有现有属性编辑位configurable:false
  4. 冻结:Object.freeze(…):该方法会创建一个冻结对象,这歌方法会在现有对象上调用Object.seal(…)并把所有数据访问属性标记为writeable:false

3.3.7 [Get]
看如下代码:

var myObject = {
    a: undefined
}

myObject.a; // undefined
myObject.b; // undefined

myObject.a 实际上执行了[get]操作(有点像函数调用:[get])。对象内置的[get] 操作首先在对象中查找是否有名称相同的属性,如果找到就会返回这个值。
而像myObject.b没有找到的话,会执行另一个种非常重要的行为。(即原型链)。尽管myObject.a和myObject.b 都返回了undefined ,但是实际上底层的[get]对object.b进行了更复杂的处理。

3.3.8: 【Put】
【Put】被触发时,实际的行为取决于许多对象,包括对象中是否已经存在这个属性。
如果已经存在这个属性,会检查以下内容:

  1. 属性是否是访问描述符?如果是并且存在setter就调用setter
  2. 属性的数据描述符中writable 是否是false?如果是,在非严格模式下静默失败,在严格模式下抛出TypeError异常。
  3. 如果都不是,将该值设置为属性的值。

3.3.9 Getter和Setter

分别可以控制属性值的设置和获取。

3.3.10存在性
我们可以在不访问属性值的情况下判断对象中是否存在这个属性。

var myObecjt = {
    a: 2
}

myObject.hasOwnProperty(“a”); // true
myObject.hasOwnProperty(“b”); // false

3.4: 遍历

有几种遍历的方式呢?

  1. fo…in :用了遍历对象的可枚举属性列表(包含Prototype链)
  2. forEach(…):会遍历数组中的所有值并忽略回调函数的返回值。
  3. every(…):一直运行直到回调函数返回false
  4. some(…):一直运行直到回调函数返回true
  5. for…of: 首先会访问被访问对象请求一个迭代器对象,然后通过调用迭代器对象的next()方法来遍历所有返回值。
var myArray = [1, 2, 3];
var it = myArray[Symbol.iterator]();

it.next(); // {value:1, done: false}
it.next(); // {value:2, done: false}
it.next(); // {value:3, done: false}
it.next(); // {done: true}

三:这一章跟你有什么关系?

对象的全面解析,是js语言的重点啊,熟悉底层原理是很重要的。

四:本章小结:

  1. Js中的对象有字面形式(var a = {…})和构造形式(var a = new Array(…))。字面形式更常用,不过有时构造形式可以提供更多选项。
  2. 许多人都认为“JavaScript 中万物都是对象”,这是错误的。对象是6个基础类型之一。对象有包括function在内的子类型,不同子类型具有不同的行为,比如内部标签[object Array ]表示这是对象的子类型数组。
  3. 对象就是键/值 对 的集合,可以通过.propName或者 [“propName”]语法来获取属性值。访问属性时,引擎实际上会调用内部的默认[Get]操作,[Get]操作会检查对象本身是否包含这个属性,如果没找到的话还会查找[Prototype]链
  4. 属性的特性可以通过属性描述符来控制,比如writable和configurable.此外,可以使用Object.preventExtensions(…) \ Object.seal(…) \ Object.freeze(…)来设置对象的不可变性级别。
  5. 属性不一定包含值—它们可能是具备getter/setter 的“访问描述符”。此外,属性可以时可枚举或者不可枚举的,这决定了它们是否会出现在for…in循环中。
  6. 你可以使用for…of语法来遍历数据结构(数组、对象,等等)中的值,for…of会寻找内置或自定义的@@iterator对象并调用它的 next()方法来遍历数据值。
上一篇下一篇

猜你喜欢

热点阅读