一、对象

对象是一种复合值,他将很多值(原始值或者其他对象)聚合在一起,可以通过名字访问这些值。对象也可以看做是属性的无序集合,每个属性嗾使一个名/值对。属性名是字符串,因此我们可以吧对象看做是从字符串到值的映射。
对象最常见的用法是创建(create)、设置(set)、查找(query)、删除(delete)、检测(test)和枚举它的属性。一下将分别介绍。

1.1 创建对象

创建对象可以通过对象直接量、关键字new和Object.create()函数来创建对象

1.1.1 对象直接量

创建对象最简单的方式就是使用对象直接量。属性名默认是字符串,因此写属性名时可以写单引号或双引号,也可以不写(注:若属性名称不符合简单标识符的要求,属性名必须使用引号)。如下:

  1. var empty = {} //没有任何属性的对象
  2. var point = {x: 0, y: 1} //两个属性
  3. var book = {
  4. name: 'javascript', //属性名可以不使用引号
  5. 'author': 'tony'
  6. "from": '贵阳市图书馆'
  7. "create-time": '2019-9-21', //属性名不符合简单标识符的要求,必须使用引号
  8. '001code': true //属性名不符合简单标识符的要求,必须使用引号
  9. }

1.1.2 通过new创建对象

new运算符创建并初始化一个对象。关键字new后跟随一个函数调用。这里的函数称为构造函数。JavaScript语言核心中的原始类型都包含内置的构造函数。例如:

  1. var o = new Object(); //创建一个空对象,和{}一样
  2. var arr = new Array(); //创建一个数组对象,和[]一样
  3. var date = new Date(); //创建一个表示当前时间的Date对象

1.1.3 Object.create()

ECMAScript 5 定义了一个名为Object.create()的方法,它创建一个新对象,其中第一个参数是这个对象的原型。例如:

  1. var obj = Object.create({x: 1, y:2}) //obj继承了属性x和y

可以通过传入null来创建一个没有原型的新对象,但通过这种方式创建的对象不会继承任何东西,甚至不包括基础方法,比如toString()

  1. var obj = Object.create(null) //obj不继承任何属性和方法

如果想创建一个普通的空对象,需要传入Object.prototype:

  1. var obj = Object.create(Object.prototype) //和{}或 new Object()一样

1.2 属性的设置和查询

1.2.1 属性的查询

查询属性的值可以使用 (.) 或 ([])运算符,需要注意的是:对于(.)来说,右侧必须是和属性名称一样的简单标识符(不知道标识符的自行查询)。而对于([])来说,方括号内必须是计算结果为字符串的表达式,这个字符串就是属性的名字。即:使用点运算符要求属性名必须是符合标识符要求的名称,使用方括号运算符要求方括号内必须是字符串。

  1. var book = {
  2. name: 'javascript',
  3. author: 'tony',
  4. "create-time": '2019-9-21'
  5. }

如上对象,取其属性时,name和author可以使用点运算符或方括号运算符,但是create-time属性只能使用方括号运算符。如下:

  1. var name = book.name,name = book['name'];
  2. var author = book.author,author = book['author']
  3. var createTime = book.create-time //报错 必须使用 createTime = book['create-time']

1.2.2 属性的设置

属性的设置方法与属性的取值方法一样,都可以使用(.)或 ([])运算符。如下:

  1. book.name = 'javascript第一版'
  2. book["create-time"] = '2000-1-1';

1.2.3 什么时候使用([])运算符?

  1. 当属性名不符合简单标识符要求是时,实例看上面 book[“create-time”] = ‘2000-1-1’;
    2.当属性名称不确定时,例如(代码运行完后obj就会包含三个属性test0、test1、test2)
    1. var test = "test";
    2. var obj = {};
    3. for(var i = 0; i < 3; i++) {
    4. obj[test + i] = i;
    5. }

    1.3 删除属性

    delete运算符可以删除对象的属性。
    1. delete book.name //book不再有name属性
    2. delete book['create-time'] //book不再有‘create-time’属性

    delete运算符只能删除自有属性,不能删除继承属性。当delete表达式删除成功或没有任何副作用时(比如删除不存在的属性),它返回true
    1. var o ={x:1}; // o有一个属性x,并継承属性toString
    2. delete o.x; //刪除x,返回true
    3. delete o.x; //什么都没做(x已経不存在了) ,返回true
    4. delete o.toString; //什么也没做(toString是継承来的) ,返回true
    5. delete 1; //无意义,返回true

    1.4 检查属性

    判断某个属性是否存在于某个对象中,可以通过in运算符、hasOwnPreperty(‘属性名’)方法 和propertyIsEnumerable(“属性名”)方法来实现

    1.4.1 in运算符

    in运算符的左侧是属性名(字符串),右侧是对象。如果对象的自有属性或继承属性中包含这个属性则返回true
    1. var o = {x: 1};
    2. "x" in o ; //true, "x"是o的属性
    3. "y" in o; //false, "y" 不是o的属性
    4. "toString" in o; //true, o继承toString属性

    1.4.2 hasOwnPreperty(‘属性名’)方法

    对象的 hasOwnPreperty(‘属性名’)方法用来检测给定的名字是否是对象的自有属性。对于继承属性,它的返回值是false
    1. var o = {x: 1};
    2. o.hasOwnProperty("x") //true, o有一个自有属性x
    3. o.hasOwnProperty("y") //false, o不存在属性y
    4. o.hasOwnProperty("toString") //false, toString是继承属性

    1.4.3 propertyIsEnumerable(“属性名”)方法

    只有检测到是自有属性且这个属性是可枚举的它才返回true
    1. var o = inherit({y: 2});
    2. o.x = 1;
    3. o.propertyIsEnumerable("x") //true , o有一个可枚举的自有属性
    4. o.propertyIsEnumerable("y") //false , y是继承来的属性
    5. Object.prototype.propertyIsEnumerable("toString") //false, 不可枚举

1.5 枚举属性

1.5.1 for/in遍历对象属性

除了检测属性是否存在,通常还需要遍历属性。通常使用for/in遍历,for/in循环可以遍历对象中所有可枚举的属性(包括自有属性和继承属性),它把属性名称赋值给循环变量。对象继承的内置方法不可枚举,但在代码中给对象添加的属性都是可枚举的。例如:

  1. var o = {x: 1, y:2, z: 3};
  2. o.propertyIsEnumerable("toString") //false, 不可枚举
  3. for(let key in o) {
  4. console.log(key) //输出x,y,z ,不会输出toString
  5. }


 在遍历对象属性的过程中,有时候可能不需要对象继承的属性,或不需要对象中的方法,可以使用以下方法过滤

for(let p in o) {
    if (!o.hasOwnProperty("p")) {  //跳过继承的属性
      continue;
  }
}
for(let p in o) {
    if (typeof o[p] === 'function') {  //跳过方法
      continue;
  }
}

1.5.2 Object.keys(对象) 和 Object.getOwnPropertyNames(对象);

ECMAScript 5 定义了两个用以枚举属性名的函数。第一个是Object.keys(对象),它返回一个数组,这个数组由对象中可枚举的自有属性组成,第二个是Object.getOwnPropertyNames(对象),它返回一个数组,这个数组由对象中所有的自有属性组成,而不仅仅是可枚举的自有属性。例如:
1667240-20190921154648030-406066413.png
1667240-20190921154743436-2137141622.png
1667240-20190921154801344-135196990.png