Object的方法简单整理
[[toc]]
Object.create()
描述:该方法创建一个新对象,将对象继承到proto属性上
格式:Object.create(proto[, propertiesObject])
用法:如果用传统的方法要给一个对象的原型上添加属性和方法,是通过 propt 实现的
通过构造函数
var People = function(){} People.prototype.y = 20 People.prototype.z = 40 People.prototype.showNum = function() {}
var p = new People(); console.log(p.__proto__ === People.prototype)
|
使用Object.create()
var proto = { y: 20, z: 40, showNum(){} }; var o = Object.create(proto);
|
Object.defineProperty()
Object.defineProperty(obj, prop, descriptor)
obj: 需要被操作的目标对象
prop: 目标对象需要定义或修改的属性的名称
descriptor: 将被定义或修改的属性的描述符
var obj = new Object();
Object.defineProperty(obj, 'name', { configurable: false, writable: true, enumerable: true, value: '张三' })
console.log(obj.name)
|
对象的数据属性
var person = {} Object.defineProperty(person,'name',{ configurable:false, enumerable:false, writable:false, value:'xiaoming' });
console.log(person);
person.name="666"; console.log(person);
for(var i in person){ console.log(person[i]) } Object.keys(person) Object.getOwnPropertyNames(person)
delete person.name console.log(person.name)
Object.defineProperty(person,'name',{ configurable:true });
Object.getOwnPropertyDescriptor(person,'name') { configurable: false enumerable: false value: "xiaoming" writable: false }
|
Object.defineProperties()
Object.defineProperties(obj, props)
obj: 将要被添加属性或修改属性的对象
props: 该对象的一个或多个键值对定义了将要为对象添加或修改的属性的具体配置
var obj = new Object(); Object.defineProperties(obj, { name: { value: '张三', configurable: false, writable: true, enumerable: true }, age: { value: 18, configurable: true } })
console.log(obj)
|
Object.getPrototypeOf()
描述:用于读取一个对象的原型对象;
格式:Object.getPrototypeOf(obj);
用法:
Object.getPrototypeOf('foo') === String.prototype === 'foo'.__proto__ Object.getPrototypeOf(true) === Boolean.prototype === true.__proto__
|
Object.setPrototypeOf(
描述: Object.setPrototypeOf方法的作用与_proto_相同,用来设置一个对象的prototype对象,返回参数对象本身
格式:Object.setPrototypeOf(object, prototype)
该方法等同于下面的函数:
function (obj, proto) { obj.__proto__ = proto; return obj; }
|
示例
let proto = {}; let obj = { x: 10 }; Object.setPrototypeOf(obj, proto); proto.y = 20; proto.z = 40; obj.x obj.y obj.z
|
keys & values & entries
- Object.keys 键
- Object.values 值
- Object.entries 组件二级数组
const obj = { address: "434343422", admin: "3434", adminCharater: '4444', adminRecord: '33', article: '22', artist: '11' } Object.entries(obj) Object.keys(obj) Object.values(obj)
|
for (const value of Object.values(obj)) { console.log(value); }
for (const value in obj) { console.log(value); }
|
Object.keys、Object.getOwnPropertyNames区别
var obj = { "prop1": "v1" }; Object.defineProperty(obj, "prop2", { value: "v2", writable: false }); console.log(Object.keys(obj).length); console.log(Object.getOwnPropertyNames(obj).length);
|
内置的判断,访问和迭代方法
功能 |
可枚举(writable:true) |
可枚举、不可枚举 |
判断 |
propertyIsEnumerable |
in/hasOwnProperty |
访问 |
Object.keys |
Object.getOwnPropertyNames |
迭代 |
for..in.. |
Object.getOwnPropertyNames |
Object 的 set 和 get 用法
在初始化对象的时候这样使用
var obj={ a: 1, b: 2, set c(x){console.log('c被赋值:',x);c=x;}, get c(){console.log('c被取出: ',c);return c} };
obj.c=3 obj.c
|
对象初始化之后可以这样添加属性
var obj={ a: 1, b: 2 };
obj.__defineGetter__('c', function(){return c}); obj.__defineSetter__('c', function(x){c = x});
|
或者使用
Object.defineProperty(obj, c, { set:function(x){ console.log('c被赋值:',x); c=x }, get:function(){ console.log('c被取出:',c) return c } }) obj.c=3 obj.c
|
Object.fromEntries()
ES10新增
const entries = new Map([ ['foo', 'bar'], ['baz', 42] ]);
const obj = Object.fromEntries(entries);
console.log(obj);
|
lodash/pick
function basePickBy(obj, props, predicate) { return props.reduce((acc, key) => { predicate(obj[key], key) && (acc[key] = obj[key]); return acc; }, {}); }
function pick(obj, props) { return basePickBy(obj, props, (value, key) => key in obj); }
let data = {message: "Foo", a: 11, b: 2, c: 3} pick(data,['a','b'])
|
结果同上:
JSON.parse(JSON.stringify(data,['a','b']))
|
浅拷贝/深拷贝
const clone = source => Object.assign({}, source) const clone = source => { ...source }
|
function deepclone(obj){ if (typeof obj === 'object' && obj !== null) { let o = obj.push?[]:{}; console.log(obj.push); for(let attr in obj){ if(obj.hasOwnProperty(attr)){ if(typeof obj[attr] === 'object'){ o[attr] = deepclone(obj[attr]); }else{ o[attr] = obj[attr]; } } } return o; } else { return obj; } }
const obj = {val:2}; obj.target = obj;
JSON.parse(JSON.stringify(obj));
const isObject = (target) => (typeof target === 'object' || typeof target === 'function') && target !== null;
const deepClone = (target, map = new Map()) => { if(map.get(target)) return target; if (isObject(target)) { map.set(target, true); const cloneTarget = Array.isArray(target) ? []: {}; for (let prop in target) { if (target.hasOwnProperty(prop)) { cloneTarget[prop] = deepClone(target[prop],map); } } return cloneTarget; } else { return target; } }
const deepClone = (target, map = new WeakMap()) => { }
|
对象转原始类型是根据什么流程运行的?
对象转原始类型,会优先调用内置的[ToPrimitive]函数,对于该函数而言,其逻辑如下:
如果Symbol.toPrimitive()方法,优先调用再返回
调用valueOf(),如果转换为原始类型,则返回
调用toString(),如果转换为原始类型,则返回
如果都没有返回原始类型,会报错
const obj = { value: 3, valueOf() { return 4; }, toString() { return '5' }, [Symbol.toPrimitive]() { return 6 } } console.log(obj + 1);
|
如何让if(a == 1 && a == 2)条件成立?
就是上面例子的应用
const a = { value: 0, valueOf() { this.value++; return this.value; } }; console.log(a == 1 && a == 2,a);
|
对象比较
hashcode
javascript 对象的比较是比较坑爹的一件事,因为javascript对象比较的是引用地址,当两个引用地址相同的对象总是相等的,或者两个完全一样的对象也是不相等的。
var object1={ name:"1234 ", code:123, test:"321", }; var object2={ name:"1234 ", code:123, test:"321", };
console.log(object1===object2)
|
解决方法使用hashcode
这里只是简单的走个流程,详细的请查看js-hash-code
function hashCode(str) { let hash = 0, i, chr, len; if (str.length === 0) return hash; for (i = 0, len = str.length; i < len; i++) { chr = str.charCodeAt(i); hash = ((hash << 5) - hash) + chr; hash |= 0; } return hash; }
|
<<是移位符
移位运算就是对二进制进行有规律低移位。移位运算可以设计很多奇妙的效果,在图形图像编程中应用广泛。
|= 按位或.然后赋值.
i=1;//二进制为0001 i|2;//2的二进制为0010 两个按位或为0011也就是3 i|=2等价于i=i|2;
|
console.log(object1===object2);
var test1=hashCode(JSON.stringify(object1)); var test2=hashCode(JSON.stringify(object2)); console.log(test1,test2,test1===test2);
|
递归
const isEqual = (obj1, obj2) => { if(obj1 === obj2) return true; let isObj1 = obj1 instanceof Object; let isObj2 = obj2 instanceof Object; if (!isObj1 || !isObj2) return Object.is(obj1, obj2);
let kyes1 = Object.keys(obj1); let kyes2 = Object.keys(obj2);
if (kyes1.length !== kyes2.length) return false;
for (let item in kyes1) { if (!kyes2.includes(kyes1[item])) { return false } } for (let attr in obj1) { let t1 = obj1[attr] instanceof Object; let t2 = obj2[attr] instanceof Object; if (t1 && t2) { return isEqual(obj1[attr], obj2[attr]); } else if (obj1[attr] !== obj2[attr]) { return false; } } return true; }; return true;
|
参考文档
MDN OBJECT