Javascript 对象

70 阅读2分钟

创建对象

使用

方法一

var obj = {};

方法二

var obj = Object.create(null);

方法三

var obj = new Object;

原理

方法一原理

let obj;
obj.__proto__ = Object.prototype 

方法二的原理

Object.create = function(proto,propertiesObject){
    if(typeof proto != 'object' && proto !== null){
        throw new Error('the first param must be an object or null');
    }
    if(typeof propertiesObject === null){
        throw 'TypeError';
    }
    let obj = {};
    obj.__proto__ = proto;
    if(propertiesObject){
        Object.defineProperties(obj,propertiesObject);
    }
    return obj;
}

方法三的原理

function _new(Fn,...args){
    if(typeof Fn !== 'function'){
        throw 'error';
    }
    let obj = {};
    obj.__proto__ = Fn.prototype; 
    Fn.apply(obj,args);
    return obj;
}

以下三者是等价的

let obj = {};
let obj = Object.create(Object.prototype);
let obj = new Object;

添加属性

方法一

var obj ={name : "mike", age : 18};

方法二

var obj = {};
obj.name = "mike";

方法三

var obj = {};
Reflect.defineProperty(obj,'name',{value:'mike'});

方法四

function Person(){
    this.name = "mike";
    this.age = 18;
}
var obj = new Person();

删除属性

var obj = {name:'mike'};
Reflect.deleteProperty(obj,'name');

访问属性

obj.name;//mike
obj[name];
obj[na+me];
Reflect.get(obj,'name');

对象权限设置

Reflect.preventExtensions方法可以使得一个对象无法再添加新的属性。

Object.seal方法使得一个对象既无法添加新属性,也无法删除旧属性。

Object.freeze方法可以使得一个对象无法添加新属性、无法删除旧属性、也无法改变属性的值,使得这个对象实际上变成了常量。

属性权限设置

每个对象属性都有一个属性描述符,属性描述对象提供6个元属性,用于设置属性权限。

{
  value: 123,
  writable: false,
  enumerable: true,
  configurable: false,
  get: undefined,
  set: undefined
}

value

value是该属性的属性值,默认为undefined

writable

writable是一个布尔值,表示属性值是否可改变(即是否可写),默认为true

enumerable

enumerable是一个布尔值,表示该属性是否可遍历,默认为true。如果设为false,会使得某些操作(比如for...in循环、Object.keys())跳过该属性。

configurable

configurable是一个布尔值,表示可配置性,默认为true。如果设为false,将阻止某些操作改写该属性,比如无法删除该属性,也不得改变该属性的属性描述对象(value属性除外)。也就是说,configurable属性控制了属性描述对象的可写性。

get

get是一个函数,表示该属性的取值函数(getter),默认为undefined

set

set是一个函数,表示该属性的存值函数(setter),默认为undefined

可以通过这个函数获取属性描述符

Reflect.getOwnPropertyDescriptor(target, name)

可以通过这个函数修改属性描述符

Reflect.defineProperty(target, name, desc)

var obj = Object.defineProperty({}, 'p', {
  get: function () {
    return 'getter';
  },
  set: function (value) {
    console.log('setter: ' + value);
  }
});

obj.p // "getter"
obj.p = 123 // "setter: 123"

对象操作函数

Reflect.apply(target, thisArg, args)
Reflect.construct(target, args)
Reflect.get(target, name, receiver)
Reflect.set(target, name, value, receiver)
Reflect.defineProperty(target, name, desc)
Reflect.deleteProperty(target, name)
Reflect.has(target, name)
Reflect.ownKeys(target)
Reflect.isExtensible(target)
Reflect.preventExtensions(target)
Reflect.getOwnPropertyDescriptor(target, name)
Reflect.getPrototypeOf(target)
Reflect.setPrototypeOf(target, prototype)