JavaScript系列之内置对象(二):Object

创建对象

Object.create()

该方法可以使用一个已有对象来创建一个新的对象,Object.create(proto[, propertiesObject])

  • proto:原型对象
  • propertiesObject:需要给新建对象添加的可枚举属性。
let zeng = {};
let person = Object.create(zeng, {
    name: {
        set(value) {
            console.warn('你重新设置了你的名字: ', value)
        },
        configurable: true,
        get() {
            return value;
        }
    }
});
person.name = '曾';

如果浏览器不支持:

if (typeof Object.create !== "function") {
    Object.create = function (proto, propertiesObject) {
        if (typeof proto !== 'object' && typeof proto !== 'function') {
            throw new TypeError('Object prototype may only be an Object: ' + proto);
        } else if (proto === null) {
            throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.");
        }

        if (typeof propertiesObject != 'undefined') throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument.");

        function F() {}
        F.prototype = proto;

        return new F();
    };
}

拷贝对象

Object.assgin()

源对象所有可枚举的值拷贝到目标对象

  • 如果目标对象拥有源对象相同的属性,值会被覆盖。
  • null或者undefined也会被复制。
var obj = { a: 1 };
var copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }

这种写法都是浅拷贝,拷贝后的对象会影响到源对象:

let zeng = {
    name: 'z', qq: {
        num: '10086'
    }
};

let assign = Object.assign({}, zeng);
assign.qq.num = '70479872';
console.log(zeng.qq.num); // 704729872

深拷贝

let zeng = {
    name: 'z', qq: {
        num: '10086'
    }
};
let parse = JSON.parse(JSON.stringify(zeng));
parse.qq.num = '704729872';
console.log(zeng.qq.num); // 10086

继承属性和不可枚举属性不能被拷贝,因为拷贝是基于遍历去完成的。

冻结对象

Object.freeze()

冻结之后,不能对该对象有任何的操作,冻结对象和此方法返回的对象都是不可被操作的。

Object.freeze(obj)

如果此对象其中一个属性的值是个对象,那这个对象中的属性是可以修改的,除非这个属性也是个冻结对象。

这个方法返回传递的对象,而不是创建一个被冻结的副本。

对比Object.seal()

Object.seal()密封的对象可以改变它们现有的属性。使用Object.freeze()冻结的对象中现有属性是不可变的。

封闭对象

Object.seal()

阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要可写就可以改变。

阻止扩展

Object.preventExtensions()

让对象变的不能扩展,也就是用于不能添加新的属性。但是原属性可以被删除。

属性操作

Object.defineProperties()

这个方法能直接在一个对象上定义新的属性或修改现有属性,并返回该对象。两个参数:

  • obj:源对象
  • props:属性
  • descriptorObject.defineProperty的属性描述符

添加的属性可以有如下配置:

  • configurable:该属性能否被删除
  • writable:值能否改变
  • enumerable:能否被枚举
  • value:值
  • set:设置值
  • get:取值

它是Object.defineProperty的复数形式,使用:

var obj = {};
Object.defineProperties(obj, {
  'property1': {
    value: true,
    writable: true
  },
  'property2': {
    value: 'Hello',
    writable: false
  }
  // etc. etc.
});

Object.defineProperty

var obj = {};
// 显式
Object.defineProperty(obj, "key", {
  enumerable: false,
  configurable: false,
  writable: false,
  value: "static"
});

Object.entries()

该方法返回源对象的可枚举的属性键值对数组。Object.entries(obj)

将对象转成Map

var obj = { foo: "bar", baz: 42 }; 
var map = new Map(Object.entries(obj));
console.log(map); // Map { foo: "bar", baz: 42 }

对象判断

Object.is

判断两个对象是否相同,如果下列任何一项成立,则两个值相同:

  • 两个值都是 undefined
  • 两个值都是 null
  • 两个值都是 true 或者都是 false
  • 两个值是由相同个数的字符按照相同的顺序组成的字符串
  • 两个值指向同一个对象
  • 两个值都是数字并且

    • 都是正零 +0
    • 都是负零 -0
    • 都是 NaN
    • 都是除零和 NaN 外的其它同一个数字

相等性判断逻辑和传统的 == 运算符所用的不同,== 运算符会对它两边的操作数做隐式类型转换(如果它们类型不同),然后才进行相等性比较,(所以才会有类似 "" == falsetrue 的现象),但 Object.is 不会做这种类型转换。

这与===运算符也不一样。===运算符(和==运算符)将数字值-0和+0视为相等,并认为Number.NaN不等于NaN

Object.isExtensiable()

判断对象是否可扩展:

let zeng = {
    name: 'z', qq: {
        num: '10086'
    }
};

let readonly = Object.freeze(zeng);
readonly.name = '120';
zeng.name = '110';

console.log(Object.isExtensible(readonly)); // false

Object.isFrozen()

判断对象是否被冻结

Object.isSealed()

判断对象是否被密封

Last modification:April 6th, 2018 at 07:24 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment