JavaScript快速入门(7):对象

本系列随笔是本人的学习笔记,初学阶段难免会有理解不当之处,错误之处恳请指正。另:转载请注明出处。

简介

JavaScript 中,对象可以看做是“属性”的集合(这里的“属性”不仅是属性名,而是一个键/值对,即属性名和属性值)。

对象的创建方式

JavaScript 中可以用以下三种方式创建对象:

  1. 直接使用字面值对象(看起来同JSON格式);
  2. 使用 new 运算符创建(new 后面跟一个构造函数调用,JavaScript 中没有“类”的概念,对象是通过构造函数创建而来的)
  3. 使用 Object.create() 方法,其第一个参数指定对象的原型对象(可以理解为parent对象),第二个参数为可选参数,用以指定属性相关特性(同Object.defineProperties()的第二个参数)

示例:

var a = {};                 // #1,字面值创建方式,创建一个空对象
var b = { x: 1, y: 2 };     // #2,字面值创建方式,创建一个非空对象
var c = new Object();       // #3,通过 new 运算符创建,创建一个空对象,同 #1
var d = new Date();         // #4,通过 new 运算符创建,创建一个日期对象
var e = Object.create(Object.prototype); // #5,创建一个空对象,同 #1 和 #3
var f = Object.create(b);   // #6,创建一个继承自 b 的对象
f.x = 3;          // 并不会影响父对象 b 中的属性值
console.log(b);   // { x: 1, y: 2 }
console.log(f);   // { x: 3 },这里虽然没有输出 y 属性,但是通过 f.y 能访问 y 属性值
console.log(f.y); // 2

属性的特性

JavaScript 中,对象可以看做是“属性”的集合(这里的“属性”不仅包括属性名,还包括属性值和一组特性)。

属性的特性可以表明该属性是否为只读属性、是否可枚举、是否可配置等。

查看一个属性的特性,可以使用 Object.getOwnPropertyDescriptor() 方法,例如(下面的示例查看对象 o 中的 x 属于性的特性):

var o = { x: 1, y: 2 };
console.log(Object.getOwnPropertyDescriptor(o, "x")); // {value: 1, writable: true, enumerable: true, configurable: true}

修改某个属性的特性,可以使用 Object.defineProperty() 方法,例如:

var o = { x: 1, y: 2 };
console.log(Object.getOwnPropertyDescriptor(o, "x")); // {value: 1, writable: true, enumerable: true, configurable: true}
Object.defineProperty(o, 'x', { writable: false });   // 这里可以同时修改多个特性,也可以单独修改某个特性
console.log(Object.getOwnPropertyDescriptor(o, "x")); // {value: 1, writable: false, enumerable: true, configurable: true}

如果想要同时修改多个属性,请参考:Object.defineProperties()

如果想要在创建对象的时候指定属性特性,可通过 Object.create()  方法的第二个参数进行设置。

设置属性的 getter 和 setter 

属性值可以是一个简单的数据,这样的属性称为“数据属性”。

与之相对的,JavaScript 还支持为属性设置读写方法(getter和setter),这样的属性称为“存取器属性”。如果设置了 getter 表明该属性可读,如果设置了 setter 表明该属性可写,例如:

"use strict"
var c = {
    x: 3,
    y: 4,
    get r() { // r 设置了 getter 和 setter,所以它是个可读、可写属性
        return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2));
    },
    set r(v) {
        var ratio = v / this.r;
        this.x = this.x * ratio;
        this.y = this.y * ratio;
    },
    get s() { return Math.PI * Math.pow(this.r, 2); } // s 只设置了 getter,所以它是个只读属性
};

console.log(c.x, c.y, c.r, c.s); // 3 4 5 78.53981633974483
c.r = 10;
console.log(c.x, c.y, c.r, c.s); // 6 8 10 314.1592653589793
c.s = 20; // Uncaught TypeError: Cannot set property s of #<Object> which has only a getter,只有在严格模式下,这里才会报错

注意:

  • “数据属性”包含 value、writable、enumerable、configurable 四个特性;
  • 而“存取器属性”因为 其值 和 writable 分别根据是否设置了 getter 和 setter 决定可否访问,因此它没有 value、writable 这两个特性,示例:
console.log(Object.getOwnPropertyDescriptor(c, "x")); // {value: 3, writable: true, enumerable: true, configurable: true}
console.log(Object.getOwnPropertyDescriptor(c, "r")); // {enumerable: true, configurable: true, get: ƒ, set: ƒ} console.log(Object.getOwnPropertyDescriptor(c, "s")); // {set: undefined, enumerable: true, configurable: true, get: ƒ}

in 与 hasOwnProperty() 的区别

in 可以检测对象的自有属性和继承属性,而 hasOwnProperty() 仅可用于检测对象的自有属性,例如:

var p = { x: 1, y: 2 };
var c = Object.create(p);
c.z = 3;
console.log("x" in c); // true
console.log("z" in c); // true
console.log(c.hasOwnProperty("x")); // false
console.log(c.hasOwnProperty("z")); // true

未完待续。

猜你喜欢

转载自www.cnblogs.com/itwhite/p/12230148.html