Object 常用属性

一、Object.defineProperty(obj, prop, descriptor);

定义或修改对象的一个属性,返回被定义的对象
数据描述符和存取描述符不能同时存在,会产生异常

参数:

  • obj:需要定义属性的目标对象
  • prop:属性名称
  • descriptor:被定义或修改的属性描述符

描述符:

configurable 定义该属性的描述符是否可修改以及该属性是否可 delete;
_通过 defineProperty 方法定义时默认为 false,显示声明赋值定义默认为 true;
_若值为 false,除了writable 可以从 true 改为 false, configurable,enumerable,writable,get,set 都不可再修改;

// 默认属性都为 false,此时 configurable 为 false,其他属性都不可修改
var a = {};
Object.defineProperty(a, 'name', { value: 'june' });
Object.defineProperty(a, 'name', { configurable: true }); // TypeError: Cannot redefine property: name
Object.defineProperty(a, 'name', { enumerable: true }); // TypeError: Cannot redefine property: name
Object.defineProperty(a, 'name', { writable: true }); // TypeError: Cannot redefine property: name
Object.defineProperty(a, 'name', { value: 'july' });  // TypeError: Cannot redefine property: name

// configurable 位 false,writable 可从 true 改为 false,但不可改回去
var a = {};
Object.defineProperty(a, 'name', { configurable: false, writable: true, value: 'june' });
console.log(a.name);  // june
a.name = 'july';
console.log(a.name);  // july
Object.defineProperty(a, 'name', { writable: false });
a.name = 'june';
console.log(a.name);  // july
Object.defineProperty(a, 'name', { writable: true });  // TypeError: Cannot redefine property: name

enumerable 定义该属性是否可被枚举;
_通过 defineProperty 方法定义时默认为 false,显示声明赋值定义默认为 true;
_定义为 false 则不可在 for...inObject.keys() 中被枚举;

var a = {};
Object.defineProperty(a, 'name', { enumerable: true, value: 'june' });
Object.defineProperty(a, 'age', { enumerable: false, value: 17 });
console.log(a); // {name: "june", age: 17}
for(var i in a) {
  console.log(a[i]);
}
// june

数据描述符(构造器属性)

writable 定义该属性的值是否能被赋值操作改变;
_通过 defineProperty 方法定义时默认为 false,显示声明赋值定义默认为 true;
_定义为 false 后,试图重新复制会被忽略,不会引发错误;

value 定义该属性的值
_默认为 undefined

存取描述符(访问器属性)

get 给属性提供的 getter 方法;
_该方法的返回值被用作属性值;
_默认为 undefined;

set 给属性提供的 setter 方法;
_该方法接收唯一参数,并将改参数处理后的新值分配给该属性;
_默认为 undefined;

function Obj() {
    var _age = 17;
    Object.defineProperty(this, 'dbAge', {
        get: function() {
            return _age;
        },
        set: function(newVal) {
            _age = newVal * 2;
        }
    })
}
var obj = new Obj();
console.log(obj.dbAge);  // 17
obj.dbAge = 10;
console.log(obj.dbAge);  // 20

二、Object.defineProperties(obj, props);

批量定义一个对象的属性,返回被定义的对象

参数:

  • obj:需要定义属性的目标对象
  • 定义属性及其描述符的对象

两种描述符的意思同上

三、Object.create(proto[, propertiesObject])

以指定对象为原型,自定义属性,创建一个新对象
返回新创建的对象

参数

  • proto:新对象的原型对象
  • propertiesObject:添加到新创建对象上的属性及其描述符,写法对应 Object.defineProperties() 的第二个参数;

注意:
若 proto 参数不是一个 null 或 Object,则抛出一个 TypeError 异常

例子:
单式继承:

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

function Rectangle() {  // 子类
  Shape.call(this);  // 继承父类实例属性
  this.z = 0;
}

Rectangle.prototype = Object.create(Shape.prototype, {
  // 以父类原型对象为原型,新添加属性,创建对象
  // 相当于父类的空实例,再添加自定义属性
  // 将新创建的对象作为子类的原型对象
  getRectangle: {
    value: function() { console.log('i am getRectangle') },
    configurable: true,
    enumerable: false,
    writable: true
  }
});
// 修改子类原型对象的构造函数指向
Rectangle.prototype.constructor = Rectangle;
var rect = new Rectangle();

多个继承:

function Sup1() {
  this.sup1 = 'sup1';
}
function Sup2() {
  this.sup2 = 'sup2';
}
function Sub() {
  Sup1.call(this);
  Sup2.call(this);
}
Sub.prototype = Object.create(Sup1.prototype);
// 此处是将第二个父类的原型属性拷贝到子类原型对象,因为是浅拷贝,故虽与第一个父类的继承有点区别,但无伤大雅
Object.assign(Sub.prototype, Sup2.prototype);
Sub.prototype.constructor = Sub;
Sub.prototype.myMethod = function() {
  // do some thing
}

Polyfill:

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 (typeof proto === null) {
      throw new Error("This browser's implementation of Object.create is a shim anddoesn't support 'null' as the first argument.")
    }
    function F() {};
    F.prototype = proto;
    return new F();
  }
}

1

你可能感兴趣的:(Object 常用属性)