Object.defineProperty
间接在一个对象上定义一个新属性,或者批改一个对象的现有属性,并返回这个对象。
-
如果增加的属性值是数组,当应用 push 等办法扭转数组,不会触发 set
const proxy = function(target,key){ let value ; Object.defineProperty(target,key,{set(val){ value = val; console.info('set') }, get(){console.info('get') return value; } }) } const obj = Object.create(null); proxy(obj,'arr'); obj.arr = []; obj.arr.push(1);
不会打印出
'set'
-
如果增加的属性值是多层级的对象,对于深层级的批改,不会触发到 set
// 紧跟后面例子 proxy(obj,'deepObj'); obj.deepObj = {a:{b:c:1}} obj.deepObj.a.b.c = 2
不会打印出
'set'
Reflect
{} vs Object.create(null)
- {} 原型链的上一层是 Object
- Object.create(null) 原型链的上一层是 null,没有继承的属性
- 所以前者会继承 Object 的属性、办法,比方 toString,后者没有
可枚举属性
可枚举属性是指那些外部“可枚举”标记设置为 true 的属性,
- 对于通过间接的赋值和属性初始化的属性,该标识值默认为即为 true,
-
对于通过 Object.defineProperty 等定义的属性,该标识值默认为 false。
const obj = Object.defineProperty({a:1},'b',{value:123}) console.info(Object.keys(obj))
只会打印出 ===>
["a"]
如果定义 b 属性的时候,设置 enumerable 为 true,就能够枚举进去啦~
Object.getOwnPropertyNames vs for…in vs Object.keys
for…in
- 遍历对象及其原型链上可枚举的属性
- 应用 for…in,就是沿着原型链,一层层网上找,直到 null
- 想查找以后实例本人有的属性,就要搭配 hasOwnProperty 来过滤了。
Object.keys
- 返回其枚举本身属性的对象
- 返回一个所有元素为字符串的数组,其元素来自于从给定的 object 下面可间接枚举的属性。这些属性的程序与手动遍历该对象属性时的统一
- 返回一个所有元素为字符串的数组
Object.getOwnPropertyNames
- 返回本身可枚举 + 不可枚举的属性名
- 该数组对元素是 obj 本身领有的枚举或不可枚举属性名称字符串。数组中枚举属性的程序与通过 for…in 循环(或 Object.keys)迭代该对象属性时统一。数组中不可枚举属性的程序未定义
- 在给定对象上找到的本身属性对应的字符串数组
JSON.stringify
JSON.stringify(value[, replacer [, space]])
replacer
- 如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会通过该函数的转换和解决
- 如果该参数是一个数组,则只有蕴含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中
- 如果该参数为 null 或者未提供,则对象所有的属性都会被序列化
space
指定缩进用的空白字符串,用于丑化输入
- 如果参数是个数字,它代表有多少的空格;下限为 10。该值若小于 1,则意味着没有空格
- 如果该参数为字符串(当字符串长度超过 10 个字母,取其前 10 个字母),该字符串将被作为空格
- 如果该参数没有提供(或者为 null),将没有空格
toJSON
如果一个被序列化的对象领有 toJSON 办法,那么该 toJSON 办法就会笼罩该对象默认的序列化行为
const a = {
a:123,
b:'222',
toJSON:function(){return 'a'}
}
const b = {
a:123,
b:'222',
c:{
d:1,
toJSON:function(){return 'a'}
}
}
console.info(JSON.stringify(a))
console.info(JSON.stringify(b))
打印出
""a""
"{"a":123,"b":"222","c":"a"}"
JSON.parse
JSON.parse(text [,reviver])
依照 JSON 的格局,
- 不容许结尾逗号
- 不容许单引号
reviver
如果是函数,它规定了在返回之前如何转换最后由解析产生的值
JSON.parse('{"1": 1,"2": 2,"3": {"4": 4,"5": {"6": 6}}}', (key, value) => {console.log(key);
return value;
});
输入
1
2
4
6
5
3
最初一个 key 是空,value 是整个值,所以:
JSON.parse('1', (key, value) => {console.log(key); // log ''
console.log(value); // log 1
return value;
});