一味宠爱|第30节 检测和枚举属性-Javascript-零点程序员-王唯( 二 )

有时需要过滤遍历 , 如:
var obj={a:1,b:2};var o = Object.create(obj);o.x=1,o.y=2,o.z=3;o.sayName = function(){}for(p in o){if(!o.hasOwnProperty(p)) continue;// 跳过继承的属性console.log(p);}for(p in o){if(typeof o[p] === "function") continue;console.log(p);// 跳过方法}用来枚举属性的工具函数:
// 把p中的可枚举属性复制到o中 , 并返回o , 如果o和p中含有同名属性 , 则覆盖function extend(o,p){for(prop in p)o[prop] = p[prop];return o;}// 如果o和p中有同名属性 , 则o中的属性不受影响function merge(o,p){for(prop in p){if(o.hasOwnProperty[prop]) continue;o[prop] = p[prop];}return o;}// 如果o和p中没有同名属性 , 则从o中删除这个属性function restrict(o,p){for(prop in p){if(!(prop in p)) delete o[prop];o[prop] = p[prop];}return o;}// 如果o和p中有同名属性 , 则从o中删除这个属性function substract(o,p){for(prop in p){delete o[prop]; // 删除一个不存在的属性也不会报错}return o;}// 返回一个新对象 , 这个对象同时拥有o和p的属性 , 如果o和p有重名属性 , 则用p的属性function union(o,p){return extend(extend({},o), p);}// 返回一个新对象 , 这个对象同时拥有o和p的属性 , 交集 , 但p中属性的值被忽略function intersection(o,p){return restrict(extend({},o), p);}// 返回一个数组 , 这个数组包含的是o中可枚举的自有属性的名字function keys(o){if(typeof o !== "object") throw TypeError;// o必须为对象var result = [];for(var prop in o){// 所有可枚举的属性if(o.hasOwnProperty(prop))// 判断是否是自有属性result.push(prop);}return result;}Object.keys()方法:取得对象上所有可枚举的实例属性 , 该方法接受一个对象作为参数 , 返回一个包含所有可枚举属性的字符串数组 , 如:
var keys = Object.keys(Person.prototype);alert(keys);// name,age,job,sayName,toStringvar p1 = new Person();p1.name = "wujing";p1.age = 28;keys = Object.keys(p1);alert(keys);// name,ageObject.getOwnPropertyNames()方法:与Object.keys()类型 , 但获得是所有实例属性 , 无论它是否可枚举如:
var keys = Object.getOwnPropertyNames(Person.prototype);alert(keys);// constructor,name,age,job,sayName,toString浅拷贝(Shallow Copy) VS 深拷贝(Deep Copy):
深拷贝和浅拷贝都是针对的引用类型 , JS中的变量类型分为值类型(基本类型)和引用类型;对值类型进行复制操作会对值进行一份拷贝 , 而对引用类型赋值 , 则会进行地址的拷贝;
浅拷贝只复制指向某个对象的指针 , 而不复制对象本身 , 新旧对象还是共享同一块内存 。 但深拷贝会另外创造一个一模一样的对象 , 新对象跟原对象不共享内存 , 修改新对象不会改到原对象 。
Js自带的深拷贝方法 , 如:数组的slice()、concat、Array.from()、... 操作符:但只能实现一维数组的深拷贝;ES6的Object.assign():只能实现一维对象的深拷贝;JSON.parse(JSON.stringify(obj)):可实现多维对象的深拷贝 , 但会忽略undefined、任意的函数、symbol 值;
function cloneJSON(source) {return JSON.parse(JSON.stringify(source));}JS 提供的自有方法并不能彻底解决Array、Object的深拷贝问题 , 因此需要自己实现;
根据拷贝的层级不同可以分为浅拷贝和深拷贝;
浅拷贝的实现方式 , 遍历对象成员 , 也就是简单地进行一层复制而已;
function shallowClone(obj) {var o = {};for(var i in obj){if(obj.hasOwnProperty(i))o[i] = obj[i];}return obj;}var obj = {a:"hello",b:{a:"world",b:18},c:["Bob","tom","Jenny"],d:function(){console.log("hello world");}}var cloneObj = shallowClone(obj);console.log(cloneObj);cloneObj.b.a = "wangwei";cloneObj.c = [1,2,3];cloneObj.d = function(){console.log("zero")};console.log(obj);


推荐阅读