zoukankan      html  css  js  c++  java
  • javascript Object的新方法

    今天复习es6,又看到Object的一堆方法,与es5的表现又有不一致,耗费了一整天,整理一下;

    前几天在司徒正美的书里又看到了es5 Object的字眼,为了向下兼容,大神们也是牛逼的整理出一系列ie仿Object方法,详情看javascript框架设计这本书(大神没有给宣传费);

    这是es5的Object的方法:

    Object.keys  Object.getOwnPropertyNames  Object.getPrototypeOf  Object.defineProperty  Object.defineProperties  Object.getOwnPropertyDescriptor  Object.create  Object.seal  Object.freeze  Object.preventExtensions  Object.isSealed  Object.isFrozen

    Object.isExtensible 

    这一堆方法看的我也是晕了,没事,我们就看看常用的(其实现在这些方法都不常用)。
    Object.getOwnPropertyNames

    用于收集当前对象不可遍历属性与可遍历属性(不包括原型链),以数组形式返回。

    //getOwnPerpertyNames()能返回出不可遍历属性,keys不能
    var obj={
        aa:1,
        to:function(){
            return 1;
        }
    }
    Object.defineProperty(obj,"name",{
        value:2 //name:2
    })
    console.log(Object.getOwnPropertyNames(obj))//含name
    console.log(Object.keys(obj));//不含name

    Object.getPrototypeOf
    返回参数对象的内部属性[[prototype]],就是标准浏览器的内置属性__proto__,此方法被es6推荐,es6自然不会让你随便操控一个内置的属性了。(第一参数必须为对象)。

    Object.defineProperty

    暴露了属性描述的接口,这些接口包括能不能被遍历,可不可写,可不可删除修改等等,与后面一些方法相关。

    var obj={}
    Object.defineProperty(obj,"a",{
        value:37,
        writable:false, //数据不能重写set
        enumerable:false//不可被for in 用getOwnPropertyNames()得到
        configurable:false //false不准删除对象属性
    })
    console.log( Object.getOwnPropertyDescriptor(obj,"a"));

    Object.defineProperties就是Object.defineProperty的加强版给个例子就明白了

    var obj={};
     Object.defineProperties(obj,{
         "value":{
             value:{
                 writable:false
             },
         "name":{
             value:"Json",
             writable:false
         }
         }
     })
     var a=1;
     for(var p in obj){
         a=p;
     } 
     console.log(a);//1

    Object.getOwnpropertyDescriptor用于获取某对象的本地属性的配置对象。其中configurable,enumerable肯定在其中,视情况再包含value,writable或set,get

    例子来啦:

     var obj={},value=0;
     Object.defineProperty(obj,
         "aaa",{
             set:function(a){
                 value:a;
             },
             get:function(){
                 return value
             }
     })
     console.log(Object.getOwnPropertyDescriptor(obj,"aaa"));//一个包含set,get,configurable,enumerable的对象
     console.log(typeof obj.aaa);//number
     console.log(obj.hasOwnProperty("aaa"));//true

    Object.create 用于创建一个子类的原型,第一个参数为父类的原型,第二个是子类另外要添加的属性的配置对象。

     Object.create(Object.prototype,{
         {x:{
             value:1,
             writable:true,
             enumerable:true,
             configurable:true
         }}
     })

    Tips:Object.create(null)还能生成一种叫纯净对象的东西,什么也没有,在Object.prototype被污染,或极需节省内存的情况下使用。

    //框架为不支持此方法模拟的Object.create()
    Object.create=function(prototype,descs){
        function f(){}
        f.prototype=prototype;
        var obj = new f();
        if (descs!=null) {
            Object.defineProperties(obj,descs);
        };
        return obj;
    }

    后面3个是关于约束对象的API
    Object.preventExtensions: 阻止添加本地属性,允许修改原有属性,不能添加本地属性,但可以添加原型属性,本地属性可被删除。对对象约束最轻
    Object.seal:不允许删除已有本地属性,不允许添加本地属性,允许修改已有属性。
    Object.freeze:无疑是最专制的,他连本地属性也不让改了。内部实现就是遍历一下,把writable都改false

     var a ={aa:"aa"}
    Object.freeze(a)
    a.bb=2;
    console.log(a.bb);//undefine
    a.aa=3;
    console.log(a.aa);//3

    tips:访问属性的复制只能通过Object.defineProperty()和Object.getOwnPropertyDescriptor()完成了

    大家懂了木?再来个例子

    function Animal(name){
        this.name=name;
    }
    Animal.prototype.getName=function(){
        return this.name;
    }
    function Dog(name,age){
        Animal.call(this,name);
        this.age=age;
    }
    Dog.prototype=Object.create(Animal.prototype,{
        getAge:{
            value:function(){
                return this.age;
            }
        },
        setAge:{
            value:function(age){
                this.age=age;
            }
        }
    })
    var dog=new Dog('dog',4);
    console.log(dog.name);//dog
    dog.setAge(6);
    sconsole.log(dog.getAge());//6

    那再开始es6的介绍吧,es6其实没有多加多少属性,大部分都是推荐了es5的方法。新加的方法也很简单,稍微介绍一下(里面包含部分es5方法)。
    那开始:
    Object.keys(Class) 求出此类的所有方法名,不包括symbol和不可遍历属性
    Object.getOwnPropertyNames(Class) 求所有属性,包括不可枚举属性,不包括symbol
    Class.hasOwnProperty()返回是不是该对象的属性,如果在类的原型链上返回false
    Tips:es6的__proto__指向父类,子类prototype.__proto__指向父类的prototype。

    Object.setPrototypeOf设置一个对象的__proto__;
    Object.setPrototypeOf的内部实现其实是

     Object.setPrototypeOf=function(obj,proto){
            obj.__proto__=proto;
            return obj;
        }

    而要实现类B继承类A即为Object.setPrototypeOf(B.prototype,A.prototype);Object.setPrototypeOf(B,A);
    所以可以判断此类是否继承了父类;Object.setPrototypeOf(子类)===父类;
    Object.is()判断两个值是否严格相等,类似于"=="
    Object.assign()这是我用的最多的方法了,经常用于复制对象,保证对象的纯净,详细了解见阮一峰的es6入门教程;
    Reflect.enumerate():返回所有for in 循环所遍历的属性
    Reflect.ownKeys(obj)返回一个数组,包含全部属性;

    还有

    ES5有三个操作会忽略enumerable为false的属性。

    for...in 循环:只遍历对象自身的和继承的可枚举的属性;而ES6规定所有class原型的方法都是不可枚举的
    Object.keys():返回对象自身的所有可枚举的属性的键名
    JSON.stringify():只串行化对象自身的可枚举的属性
    ES6新增了两个操作,会忽略enumerable为false的属性。

    Object.assign():只拷贝对象自身的可枚举的属性
    Reflect.enumerate():返回所有for...in循环会遍历的属性

    记了这么多,重要的差不多都介绍了;好多也没举例子,不过相信聪明的你一看就懂了-0-。嘿嘿

  • 相关阅读:
    Go语言new( )函数
    Go语言讲解深拷贝与浅拷贝
    (转)使用kubectl访问Kubernetes集群时的身份验证和授权
    执行kubectl命令时报错 error: You must be logged in to the server (Unauthorized)
    报错 cannot allocate memory 或者 no space left on device ,修复K8S内存泄露问题
    linux之apt-get命令(转)
    GSensor 碰撞检测方法与实现
    uboot流程(转)
    linux 环境搭建
    333开发记录
  • 原文地址:https://www.cnblogs.com/dh-dh/p/5074386.html
Copyright © 2011-2022 走看看