今天复习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-。嘿嘿