ES5新增对象的属性和方法

随笔:1、某一技术为什么而生

         2、解决了什么问题

         3、如何使用

     4、给出代码实例

ES5新增对象的方法

一、冻结对象的freeze()方法(分为深冻结和浅冻结)

var obj1 ={
      a:‘111‘  
}

obj1.a = ‘222‘;
console.log( obj.a ) //output 222 对象的属性发生了变化

现在我们来看看es5 给我提供一个对象的新方法冻结对象(浅冻结)。

Object.freeze(obj) obj是要冻结的对象,Object.freeze()可以防止对象新增属性或方法,防止删除和修改现有的属性和方法。他其实就是让对象变成不可变的数据;

 var obj = {
        a:‘111‘
    }
    Object.freeze( obj );

     obj.a = ‘222‘

    console.log( obj.a ); //output 依然是 111 严格模式下会报错  不可修改


   obj.b = ‘222‘;
    console.log( obj.b ) //output undefined 严格模式下会报错 不可新增

delete obj.a;

console.log( obj.a ) // output 依然是111 严格模式下会报错 不可删除

熟悉js对象(深浅)拷贝的朋友就知道想jQuery extend 的方法第一个参数如果出入的是布尔值true 代表深拷贝,如果忽略直接传入多个对象就代表浅拷贝。其实对象的冻结也是有深冻结和浅冻结之分的。

var obj = {
   a:{
     achild:‘deep‘  
    }  
}

Object.freeze(obj);

//我现在来改变obj对象a下的achild验证一下 Object.freeze()是否还灵验

obj.a.achild = ‘no effect‘;

console.log( obj.a.achild ) //output no effect; 果然是可以改变的。

obj.a.otherchild = ‘otherchild‘;

console.log(  obj.a.otherchild) //output otherchild 也可以新增 

delete obj.a.otherchild ;
console.log(  obj.a.otherchild) // output undefine obj.a.otherchild 不见了真名删除也是有效的

通过上面的例子我们可以发现Object.freeze(obj) 只可以浅冻结对象 obj.a(浅) obj.a.achild(深)

 那我们想深冻结一个对象怎么办?我也可以通过Object.freeze()的特性自己创建一个深冻结函数。

function deepFreeze(obj) {


  var propNames = Object.getOwnPropertyNames(obj);

  
  propNames.forEach(function(name) {
    var prop = obj[name];


    if (typeof prop == ‘object‘ && prop !== null)
      deepFreeze(prop);
  });

  return Object.freeze(obj);
}

//现在我们来试验一下我们的函数
var obj = {
    a:{}
}
deepFreeze(obj);

obj.a.achild = ‘achild‘ 

console.log( obj.a.achild ) //output undefine 现在实现了深冻结一个对象了

二、Object.create() 新增对象的方法

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()  用来判断一个对象实例的原型是否是object

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;  /*只有实例化对象之后,用此对象调用方法,传参后值不为undefined时,这个属性才显示存在*/
 
  

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 对象中以字母“n”开头的属性名。
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"]
个对象,该对象具有三个属性和一个方法。然后使用 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"






转载于:https://www.cnblogs.com/WEI-web/p/6391046.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值