代码改变世界

详解javascript,ES5标准中新增的几种高效Object操作方法

2016-09-09 10:24  流浪的诗人  阅读(3793)  评论(1编辑  收藏  举报
1、Object 对象 (JavaScript)
提供对所有 JavaScript 对象通用的功能。参考网站:https://msdn.microsoft.com/zh-cn/library/kb6te8d3(v=vs.94).aspx
2、Object.create()

概念:Object.create():是E5中提出的一种新的对象创建方式。

语法:Object.create(proto [, propertiesObject ]),第一个参数是要继承的原型,如果不是一个子函数,可以传一个null,第二个参数是对象的属性描述符,这个参数是可选的。

propertiesObject 参数的详细解释:(默认都为false)。数据属性,writable:是否可任意写;configurable:是否能够删除,是否能够被修改;enumerable:是否能用 for in 枚举;value:值;访问属性:get(): 访问;set(): 设置

示例如下:

    function Car(desc){
        this.desc = desc;
        this.color = 'red';
    }
    Car.prototype = {
        getInfo:function(){
            return 'A ' + this.color + ' ' + this.desc + '.'; 
        }
    }
    var car = Object.create(Car.prototype);
    car.color = 'blue';
    var info = car.getInfo();
    console.log(info);//A blue undefined.

        var obj = {
        a:function(){
            console.log(100);//100
        },
        b:function(){
            console.log(200)
        },
        c:function(){
            console.log(300)
        }
    }
    var newObj = {};
    newObj = Object.create(obj,{
        t1:{
            value:'yupeng',
            writable:true
        },
        bar: {
            configurable: false,
            get: function() { return bar; },
            set: function(value) { bar=value }
        }
    })

    console.log(newObj.a());//undefined
    console.log(newObj.t1);//yupeng
    newObj.t1 = 'yupeng1'
    console.log(newObj.t1);//yupeng1
    newObj.bar = 201;
    console.log(newObj.bar);//201

3、Object.keys()

Object.keys():返回一个由给定对象的所有可枚举自身属性的属性名组成的数组,数组中属性名的排列顺序和使用for-in循环遍历该对象时返回的顺序一致(两者的主要区别是 for-in 还会遍历出一个对象从其原型链上继承到的可枚举属性)。

语法:Object.keys(obj)。

参数:obj返回该对象的所有可枚举自身属性的属性名。

    var arr = ['a','b','c'];
    console.log(Object.keys(arr));//["0", "1", "2"]
    // 类数组对象
    var obj = { 0 : "a", 1 : "b", 2 : "c"};
    console.log(Object.keys(obj)); // ["0", "1", "2"]

    // getFoo是个不可枚举的属性
    var my_obj = Object.create({}, 
    {
         getFoo : { 
             value : function () { 
                 return this.foo 
             } 
         } 
     });
    my_obj.foo = 1;
    console.log(Object.keys(my_obj)); // ["foo"]

4、Object.prototype.isPrototypeOf()

isPrototypeOf:是用来判断要检查其原型链的对象是否存在于指定对象实例中,是则返回true,否则返回false。

语法:prototype.isPrototypeOf(object)。

参数:prototype,必选。对象原型。 object,必选。另一个对象,将对其原型链进行检查。

示例如下:

function person(name,age){
    this.name = name;
    this.age = age;
}
var person1 = new person('xiaoming',23);
console.log(person.prototype.isPrototypeOf(person1));//true;原型链的对象:person,对象实例;person1

5、Object.getPrototypeOf()

getPrototypeOf:返回对象的原型。

语法:Object.getPrototypeOf(object)

参数:object,必需。引用原型的对象。

返回值:object 参数的原型。原型也是对象。

function person(name,age){
    this.name = name;
    this.age = age;
}
var person1 = new person('xiaoming',23);
var proto = Object.getPrototypeOf(person1);//获取对象person1的原型
proto.eatFruit = 'apple';    //给原型添加新的属性
console.log(person1.eatFruit);//apple
var reg = /a/;
var result1 = (Object.getPrototypeOf(reg) === RegExp.prototype);//比较正则表达式对象的原型
console.log(result1 + " ");//true

var err = new Error("an error");
var result2 = (Object.getPrototypeOf(err) === Error.prototype);//比较对象原型
console.log(result2);//true

6、object.hasOwnProperty()

object.hasOwnProperty(proName):确定某个对象是否具有带指定名称的属性。

语法:object.hasOwnProperty(proName)

参数:object,必需。对象的实例。proName,必需。一个属性名称的字符串值

function person(name,age){
    this.name = name;
    this.age = age;
}
person.prototype.singsong = function(songName){
    this.songName = songName;
    console.log('singsong');
}
person.prototype.sayHello = function(){
    console.log('sayHello');
}
var person1 = new person('xiaoming',23);
var person2 = new person('angerbaby',22);
console.log(person1.hasOwnProperty("name"));//true;
console.log(person1.hasOwnProperty("age"));//true;
console.log(person1.hasOwnProperty("singsong"));//false;
console.log(person.prototype.hasOwnProperty("singsong"));//true;
console.log(person.prototype.hasOwnProperty("songName"));//false;

7、Object.getOwnPropertyNames()

Object.getOwnPropertyNames(object):返回对象自己的属性的名称。一个对象的自己的属性是指直接对该对象定义的属性,而不是从该对象的原型继承的属性。对象的属性包括字段(对象)和函数。

语法:Object.getOwnPropertyNames(object)

参数:object,必需。包含自己的属性的对象。

返回值:一个数组,其中包含对象自己的属性的名称。

function person(name,age,number){
    this.name = name;
    this.age = age;
    this.number = number;
    this.toString = function(){
        return (this.name+","+this.age+","+this.number);
    }
}
var person1 = new person('xiaoming',23,'18615244521');
var propertyArr = Object.getOwnPropertyNames(person1);
console.log(propertyArr);//["name", "age", "number", "toString"]

//下面的示例显示了使用 person 构造函数构造的 person1 对象中以字母“S”开头的属性名。
var names = Object.getOwnPropertyNames(person1).filter(checkkey);//filter(),传参为一个函数,作用为用这个函数来过滤数组元素
console.log(names);//["name", "number"]
function checkkey(value){
    var firstchar = value.substr(0,1);
    if(firstchar.toLowerCase() == 'n'){
        return true;
    }else{
        return false;
    }
}
//下面的示例创建一个对象,该对象具有三个属性和一个方法。然后使用 keys 方法获取该对象的属性和方法。
var propertyArr1 = Object.keys(person1);
console.log(propertyArr1);//["name", "age", "number", "toString"]

理解js对象中的可枚举性(enumerable):

概念:可枚举性(enumerable)用来控制所描述的属性,是否将被包括在for...in循环之中。具体来说,如果一个属性的enumerable为false,下面三个操作不会取到该属性。

  • for..in循环
  • Object.keys方法
  • JSON.stringify方法
var o = {a:1, b:2};
o.c = 3;
Object.defineProperty(o, 'd', {
  value: 4,
  enumerable: false
});
o.d
// 4

for( var key in o )
 console.log( o[key] ); 
// 1
// 2
// 3

Object.keys(o)  // ["a", "b", "c"]
JSON.stringify(o) // => "{a:1,b:2,c:3}"
//上面代码中,d属性的enumerable为false,所以一般的遍历操作都无法获取该属性,使得它有点像“秘密”属性,但还是可以直接获取它的值。
//至于for...in循环和Object.keys方法的区别,在于前者包括对象继承自原型对象的属性,而后者只包括对象本身的属性。如果需要获取对象自身的所有属性,不管enumerable的值,可以使用Object.getOwnPropertyNames方法

8、Object.defineProperty()

概念:将属性添加到对象,或修改现有属性的特性。

语法:Object.defineProperty(object, propertyname, descriptor)

参数:obj为需要定义的属性对象;prop为需定义或修改的属性的名字;descriptor为将被定义或修改的属性的描述符。
返回值:返回传入函数的对象,即第一个参数obj

对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个拥有可写或不可写值的属性。存取描述符是由一对 getter-setter 函数功能来描述的属性。描述符必须是两种形式之一;不能同时是两者。

数据描述符和存取描述符均具有以下可选键值:

  • configurable:当且仅当该属性的 configurable 为 true 时,该属性才能够被改变,也能够被删除。默认为 false。
  • enumerable:当且仅当该属性的 enumerable 为 true 时,该属性才能够出现在对象的枚举属性中。默认为 false。

数据描述符同时具有以下可选键值:

  • value:该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
  • writable:当且仅当该属性的 writable 为 true 时,该属性才能被赋值运算符改变。默认为 false。

存取描述符同时具有以下可选键值:

  • get:一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined。
  • set:一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined。

记住,这些选项不一定是自身属性,如果是继承来的也要考虑。为了确认保留这些默认值,你可能要在这之前冻结 Object.prototype,明确指定所有的选项,或者将__proto__属性指向null。

// 使用 __proto__
Object.defineProperty(obj, "key", {
  __proto__: null, // 没有继承的属性
  value: "static"  // 没有 enumerable
                   // 没有 configurable
                   // 没有 writable
                   // 作为默认值
});

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

9、Object.defineProperties()

概览:方法在一个对象上添加或修改一个或者多个自有属性,并返回该对象。

语法:Object.defineProperties(obj, props)

 参数:obj:将要被添加属性或修改属性的对象,props:该对象的一个或多个键值对定义了将要为对象添加或修改的属性的具体配置。

var obj = {};
Object.defineProperties(obj, {
  "property1": {
    value: true,
    writable: true
  },
  "property2": {
    value: "Hello",
    writable: false
  }
  // 等等.
});
alert(obj.property2) //弹出"Hello"