Open Cuuube opened 6 years ago
注:标题中的安全,较新等均指浏览器。
安全:较旧版本的浏览器都支持,甚至ie
较安全:ie9以上,火狐、chrome浏览器不能是太早期版本
较新:仅仅新版本火狐、chrome等支持,ie不支持,甚至edged都很危险
仅供参考
原型链方法
很有趣的一个方法。当将对象看做简单数据对象,进行运算时,会取valueOf的值。例:
class Person { constructor (name) { this.name = name; } valueOf () { return this.name; } } let tom = new Person('Tom'); console.log('I am ' + tom); // I am Tom
valueOf方法默认会返回this,但当我们手动设置之后,就可以返回任何东西(返回对象也可以,但最好你返回的对象也设置了valueOf,不然很可能会变得奇葩)。
valueOf
assign会将第二个参数的所有属性,都覆盖到第一个上。
let baseObj = { a: 'a', d: 'd' }; let extendObj = { a: 1, b: 2, c: 3 }; let newObj = Object.assign(baseObj, extendObj); console.log(newObj); // {a: 1, b: 2, c: 3, d: 'd'}
额外用法:经常用作obj的复制
let oldObj = { a: 1 , b: 2 }; let newObj = Object.assign({}, oldObj); console.log(oldObj === newObj); // false
jquery中也有类似的用法$.extend(),对浏览器的兼容更好。
$.extend()
用最简单的一行说明继承:
let parentObj = { a: 'a', b: 'b' }; let obj = Object.create(parentObj); console.log(obj); // {}
咦,你说怎么创建出来是空的呢,说好的继承呢?
如果你在chrome控制台中log出来看,点开这个obj的__proto__属性来,你就明白了。
__proto__
console.log(obj.__proto__); // {a: "a", b: "b"}
我们的parentObj已经跑到prototype中啦!
parentObj
但,如果你很满意,并学会了assign方法,开始举一反三,那你就悲剧了
let parentObj = { a: 'a', b: 'b' }; let obj = Object.create(parentObj, { a: 1 }); // Uncaught TypeError: Property description must be an object: 1... balabala...
因为Object.create的第二个参数并不能直接是一个一般的obj,必须是一个对象的属性名称和属性描述符的键值对,关于这个东西是什么,具体可以参考下面defineProperties的讲解,总之是一个很厉害但很麻烦的主。
Object.create
defineProperties
给对象添加新属性值。
单数,复数,调用方式不同。例:
let a = { a:1, b:2 }; // defineProperty Object.defineProperty(a, 'c', { writeable: true,// 可重复赋值 value: 3, // 值 enumerable: true,// 会出现在枚举中 configurable: true// 当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除 }) // defineProperties Object.defineProperty(a, { 'c': { writeable: true,// 可重复赋值 value: 3 // 值 }, 'd': { value: 4 // 没有writeable,默认为false,即不可更改 } })
不可拓展即是:
可使用isExtensible()检验是否被密封
isExtensible()
用法同下面
密封即是:
let obj = {a: 1, b: 2}; Object.seal(obj); obj.a = 5; // ok obj.c = 30; // no error console.log(a); // {a: 5, b: 2};
可使用Object.isSeal(obj)检验是否被密封
Object.isSeal(obj)
冻结对象即是:
let obj = {a: 1, b: 2}; Object.freeze(obj); obj.a = 5; // Type Error
可使用Object.isFrozen(obj)检验是否被冻结
Object.isFrozen(obj)
这些都是ES6的语法,keys和entries在较新版FF和chrome支持,values几乎支持的版本更新更少
keys
entries
values
example:
let a = { a: 1, b: 2 }; console.log(Object.keys(a)); // ["a", "b"] console.log(Object.values(a)); // [1, 2] console.log(Object.entries(a)); // chrome控制台打印: // (2) [Array(2), Array(2)] // 0:(2) ["a", 1] // 1:(2) ["b", 2] // length:2 // __proto__:Array(0)
一目了然:
用于比较两个object是否相同。规则和===略有区别
===
具体规则可以点击这里
此处摘出不一样的地方:
这种相等性判断逻辑和传统的 == 运算符所用的不同,== 运算符会对它两边的操作数做隐式类型转换(如果它们类型不同),然后才进行相等性比较,(所以才会有类似 "" == false 为 true 的现象),但 Object.is 不会做这种类型转换。 这与===运算符也不一样。===运算符(和==运算符)将数字值-0和+0视为相等,并认为Number.NaN不等于NaN。
这种相等性判断逻辑和传统的 == 运算符所用的不同,== 运算符会对它两边的操作数做隐式类型转换(如果它们类型不同),然后才进行相等性比较,(所以才会有类似 "" == false 为 true 的现象),但 Object.is 不会做这种类型转换。
==
"" == false
true
Object.is
这与===运算符也不一样。===运算符(和==运算符)将数字值-0和+0视为相等,并认为Number.NaN不等于NaN。
-0
+0
Number.NaN
NaN
这个方法是原型链上的方法,因此可以直接在任意obj上调用
此方法最爽的是可以判断出自己的属性,也是旧版本中的明星用法:可以做for-in的清道夫
exmple:
let obj = { a: 'a', b: 'b' }; let parentObj = { a: 1, b: 2, c: 3 }; obj.__proto__ = parentObj; // 相当于obj的原型指向了parentObj,obj继承了parentObj的属性[代码中不要这样写] console.log(obj); // { a: 'a', b: 'b' } console.log(obj.c); // 3 for (let i in obj) { console.log(i, obj[i]); } // a a // b b // c 3
如果我只想遍历子类obj的属性,不想要继承的属性,但父类的c强行抢镜。
于是。。你知道怎么办了
for (let i in obj) { if (obj.hasOwnProperty(i)) { //< 补丁 console.log(i, obj[i]); } } // a a // b b
注:标题中的安全,较新等均指浏览器。
安全:较旧版本的浏览器都支持,甚至ie
较安全:ie9以上,火狐、chrome浏览器不能是太早期版本
较新:仅仅新版本火狐、chrome等支持,ie不支持,甚至edged都很危险
仅供参考
1. valueOf 自定义对象的表示 (安全)
原型链方法
很有趣的一个方法。当将对象看做简单数据对象,进行运算时,会取valueOf的值。例:
valueOf
方法默认会返回this,但当我们手动设置之后,就可以返回任何东西(返回对象也可以,但最好你返回的对象也设置了valueOf,不然很可能会变得奇葩)。2. assign 合并和复制 (较新)
assign会将第二个参数的所有属性,都覆盖到第一个上。
额外用法:经常用作obj的复制
jquery中也有类似的用法
$.extend()
,对浏览器的兼容更好。3. create 继承 (安全)
用最简单的一行说明继承:
咦,你说怎么创建出来是空的呢,说好的继承呢?
如果你在chrome控制台中log出来看,点开这个obj的
__proto__
属性来,你就明白了。我们的
parentObj
已经跑到prototype中啦!但,如果你很满意,并学会了assign方法,开始举一反三,那你就悲剧了
因为
Object.create
的第二个参数并不能直接是一个一般的obj,必须是一个对象的属性名称和属性描述符的键值对,关于这个东西是什么,具体可以参考下面defineProperties
的讲解,总之是一个很厉害但很麻烦的主。4. defineProperties和defineProperty 创建新属性值(安全)
给对象添加新属性值。
单数,复数,调用方式不同。例:
5. preventExtensions 使object不可拓展 (较安全 )
不可拓展即是:
可使用
isExtensible()
检验是否被密封用法同下面
6. seal 密封对象 (较安全)
密封即是:
可使用
Object.isSeal(obj)
检验是否被密封7. freeze 冻结对象 (较安全)
冻结对象即是:
可使用
Object.isFrozen(obj)
检验是否被冻结8. keys, values, entries(较新)
这些都是ES6的语法,
keys
和entries
在较新版FF和chrome支持,values
几乎支持的版本更新更少example:
一目了然:
9. is 比较
用于比较两个object是否相同。规则和
===
略有区别具体规则可以点击这里
此处摘出不一样的地方:
10. hasOwnProperty 是否自己的属性存在
这个方法是原型链上的方法,因此可以直接在任意obj上调用
此方法最爽的是可以判断出自己的属性,也是旧版本中的明星用法:可以做for-in的清道夫
exmple:
如果我只想遍历子类obj的属性,不想要继承的属性,但父类的c强行抢镜。
于是。。你知道怎么办了