blog icon indicating copy to clipboard operation
blog copied to clipboard

ES5/6 object 方法整理

Open waltcow opened this issue 8 years ago • 0 comments

ES5/6 object 方法整理

Object.assign()

Object.assign() 用来复制源对象的所有可枚举属性复制到目标对象中,并且返回目标对象

Object.assign(target, ...sources)

let target = {name: 'target'};
let source1 = {age: 23};
let source2 = {email: '[email protected]'};
// ...
// let sourceN ={.....};
traget = Object.assign(target, source1, source2);

注意:

  • 如果target中的属性具有相同的key,那么它们将source中的属性覆盖。较后的source的属性也将将类似地覆盖先前的属性。
  • Object.assign() 仅仅把target 中properties可 enumerable 的属性到target对象中

Object.create()

通过指定的原型对象和属性,创建一个新的对象

Object.create(proto, [,. propertiesObject]);

实现原型继承

// Shape - superclass
function Shape() {
  this.x = 0;
  this.y = 0;
}

// superclass method
Shape.prototype.move = function(x, y) {
  this.x += x;
  this.y += y;
  console.info('Shape moved.');
};

// Rectangle - subclass
function Rectangle() {
  Shape.call(this); // call super constructor.
}

// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle);// true
console.log('Is rect an instance of Shape?', rect instanceof Shape);// true
rect.move(1, 1); // Outputs, 'Shape moved.'
var a = {a: 1}; 
// a ---> Object.prototype ---> null

var b = Object.create(a);
// b ---> a ---> Object.prototype ---> null
console.log(b.a); // 1 (继承而来)

var c = Object.create(b);
// c ---> b ---> a ---> Object.prototype ---> null

var d = Object.create(null);
// d ---> null
console.log(d.hasOwnProperty); // undefined, 因为 d 没有继承 Object.prototype

Object.freeze()

Object.freeze(obj)

将一个 object“冻住”:不能添加新的属性;不能删除现有的属性;不能修改现有属性,包括属性的 enumerability, configurability 和 writability。这个方法返回一个不可修改的对象,使用语法:

var obj = {
  prop: function() {},
  foo: 'bar'
};

// New properties may be added, existing properties may be changed or removed
obj.foo = 'baz';
obj.lumpy = 'woof';
delete obj.prop;

// Both the object being passed as well as the returned object will be frozen.
// It is unnecessary to save the returned object in order to freeze the original.
var o = Object.freeze(obj);

o === obj; // true
Object.isFrozen(obj); // === true

// Now any changes will fail
obj.foo = 'quux'; // silently does nothing
obj.quaxxor = 'the friendly duck'; // silently doesn't add the property

// ...and in strict mode such attempts will throw TypeErrors
function fail(){
  'use strict';
  obj.foo = 'sparky'; // throws a TypeError
  delete obj.quaxxor; // throws a TypeError
  obj.sparky = 'arf'; // throws a TypeError
}

fail();

// Attempted changes through Object.defineProperty will also throw
Object.defineProperty(obj, 'ohai', { value: 17 }); // throws a TypeError
Object.defineProperty(obj, 'foo', { value: 'eit' }); // throws a TypeError

深度 freeze

// To do so, we use this function.
function deepFreeze(obj) {

  // Retrieve the property names defined on obj
  var propNames = Object.getOwnPropertyNames(obj);

  // Freeze properties before freezing self
  propNames.forEach(function(name) {
    var prop = obj[name];

    // Freeze prop if it is an object
    if (typeof prop == 'object' && prop !== null)
      deepFreeze(prop);
  });

  // Freeze self (no-op if already frozen)
  return Object.freeze(obj);
}

obj2 = {
  internal: {}
};

deepFreeze(obj2);
obj2.internal.a = 'anotherValue';
obj2.internal.a; // undefined

Object.defineProperty()

Object.defineProperty(obj, prop, descriptor)

关于descriptor相关的属性

  • configurable:可配置性,控制着其描述的属性的修改,表示能否修改属性的特性,能否把属性修改为访问器属性,或者能否通过 delete 删除属性从而重新定义属性。默认值为 true。
  • enumerable:可枚举性,表示能否通过 for-in 遍历得到属性。默认值为 true。
  • value: 数据属性,表示属性的值。默认值为 undefined。
  • writable: 可写性,表示能否修改属性的值。默认值为 true。

和两个存取器属性

  • get:在读取属性时调用的函数。只指定 get 则表示属性为只读属性。默认值为 undefined。
  • set:在写入属性时调用的函数。只指定 set 则表示属性为只写属性。默认值为 undefined。
var o = {}; // Creates a new object

// Example of an object property added with defineProperty with a data property descriptor
Object.defineProperty(o, 'a', {
  value: 37,
  writable: true,
  enumerable: true,
  configurable: true
});
// 'a' property exists in the o object and its value is 37

Object.defineProperties()

Object.defineProperties(obj, props)

Object.defineProperty 升级版本,可以一次同时定义多个属性,语法略有不同:

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

Object.keys()

Object.keys(obj)

以数组的形式返回对象中自身可枚举的属性

var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']

// array like object
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj)); // console: ['0', '1', '2']

// array like object with random key ordering
var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(an_obj)); // console: ['2', '7', '100']

// getFoo is property which isn't enumerable
var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
my_obj.foo = 1;

console.log(Object.keys(my_obj)); // console: ['foo']

Mozilla

waltcow avatar Feb 10 '17 08:02 waltcow