关于es6中常见的一些方法----对象篇
好了,话不多说,是骡子是马拉出来溜溜,这篇文章笔者就来简单介绍下关于对象的一些方法
1、Object.is() Object.is()
方法判断两个值是否是相同的值。
参数:
value1: 第一个需要比较的值
value2: 第二个需要比较的值
返回值:表示两个参数是否相等的布尔值
描述:
Object.is()
判断两个值是否相同。如果下列任何一项成立,则两个值相同:
这种相等性判断逻辑和传统的 ==
运算不同,==
运算符会对它两边的操作数做隐式类型转换(如果它们类型不同),然后才进行相等性比较,(所以才会有类似 "" == false
等于 true
的现象),但 Object.is
不会做这种类型转换。
这与 ===
运算符的判定方式也不一样。===
运算符(和==
运算符)将数字值 -0
和 +0
视为相等,并认为 Number.NaN
不等于 NaN
。
示例:
Object.is('foo', 'foo'); // true Object.is(window, window); // true Object.is('foo', 'bar'); // false Object.is([], []); // false var foo = { a: 1 }; var bar = { a: 1 }; Object.is(foo, foo); // true Object.is(foo, bar); // false Object.is(null, null); // true // 特例 Object.is(0, -0); // false Object.is(-0, -0); // true Object.is(NaN, 0/0); // true
2、Object.isExtensible()
方法判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。
参数:
- obj 需要检测的对象
- 返回值:表示给定对象是否可扩展的一个
Boolean
。 - 描述: 默认情况下,对象是可扩展的:即可以为他们添加新的属性。以及它们的
__proto__
属性可以被更改。Object.preventExtensions
,Object.seal
或Object.freeze
方法都可以标记一个对象为不可扩展(non-extensible)。 - 示例:
// 新对象默认是可扩展的. var empty = {}; Object.isExtensible(empty); // === true // ...可以变的不可扩展. Object.preventExtensions(empty); Object.isExtensible(empty); // === false // 密封对象是不可扩展的. var sealed = Object.seal({}); Object.isExtensible(sealed); // === false // 冻结对象也是不可扩展. var frozen = Object.freeze({}); Object.isExtensible(frozen); // === false
注意:在 ES5 中,如果参数不是一个对象类型,将抛出一个 TypeError
异常。在 ES6 中, non-object 参数将被视为一个不可扩展的普通对象,因此会返回 false 。
Object.isExtensible(1); // TypeError: 1 is not an object (ES5 code) Object.isExtensible(1); // false (ES6 code)
3、Object.preventExtensions()
方法让一个对象变的不可扩展,也就是永远不能再添加新的属性。
参数:obj
将要变得不可扩展的对象。
返回值: 已经不可扩展的对象。
描述:如果一个对象可以添加新的属性,则这个对象是可扩展的。Object.preventExtensions()
将对象标记为不再可扩展,因此它将永远不会具有超出它被标记为不可扩展的属性。注意,一般来说,不可扩展对象的属性可能仍然可被删除。尝试将新属性添加到不可扩展对象将静默失败或抛出TypeError
(最常见但不排除其他情况,如在strict mode中)。
Object.preventExtensions()
仅阻止添加自身的属性。但属性仍然可以添加到对象原型。一旦使其不可扩展,就无法再对象进行扩展。
示例:
// Object.preventExtensions将原对象变的不可扩展,并且返回原对象. var obj = {}; var obj2 = Object.preventExtensions(obj); obj === obj2; // true // 字面量方式定义的对象默认是可扩展的. var empty = {}; Object.isExtensible(empty) //=== true // ...但可以改变. Object.preventExtensions(empty); Object.isExtensible(empty) //=== false // 使用Object.defineProperty方法为一个不可扩展的对象添加新属性会抛出异常. var nonExtensible = { removable: true }; Object.preventExtensions(nonExtensible); Object.defineProperty(nonExtensible, "new", { value: 8675309 }); // 抛出TypeError异常 // 在严格模式中,为一个不可扩展对象的新属性赋值会抛出TypeError异常. function fail() { "use strict"; nonExtensible.newProperty = "FAIL"; // throws a TypeError } fail(); // 一个不可扩展对象的原型是不可更改的,__proto__是个非标准魔法属性,可以更改一个对象的原型. var fixed = Object.preventExtensions({}); fixed.__proto__ = { oh: "hai" }; // 抛出TypeError异常
注意:
Object.preventExtensions(1); // TypeError: 1 is not an object (ES5 code) Object.preventExtensions(1); // 1 (ES2015 code)
在 ES5 中,如果参数不是一个对象类型,将抛出一个TypeError
异常。在 ES2015 中,非对象参数将被视为一个不可扩展的普通对象,因此会被直接返回。
4、hasOwnProperty()
方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性;
参数: prop
要检测的属性 字符串
名称或者 Symbol
。
返回值: 用来判断某个对象是否含有指定的属性的 Boolean
。
描述:所有继承了 Object
的对象都会继承到 hasOwnProperty
方法。这个方法可以用来检测一个对象是否含有特定的自身属性;和 in
运算符不同,该方法会忽略掉那些从原型链上继承到的属性。
示例:
使用 hasOwnProperty 方法判断属性是否存在节 下面的例子检测了对象 o 是否含有自身属性 prop: o = new Object(); o.prop = 'exists'; function changeO() { o.newprop = o.prop; delete o.prop; } o.hasOwnProperty('prop'); // 返回 true changeO(); o.hasOwnProperty('prop'); // 返回 false 自身属性与继承属性节 下面的例子演示了 hasOwnProperty 方法对待自身属性和继承属性的区别: o = new Object(); o.prop = 'exists'; o.hasOwnProperty('prop'); // 返回 true o.hasOwnProperty('toString'); // 返回 false o.hasOwnProperty('hasOwnProperty'); // 返回 false 遍历一个对象的所有自身属性节 下面的例子演示了如何在遍历一个对象的所有属性时忽略掉继承属性,注意这里 for...in 循环只会遍历可枚举属性,所以不应该基于这个循环中没有不可枚举的属性而得出 hasOwnProperty 是严格限制于可枚举项目的(如同 Object.getOwnPropertyNames())。 var buz = { fog: 'stack' }; for (var name in buz) { if (buz.hasOwnProperty(name)) { alert("this is fog (" + name + ") for sure. Value: " + buz[name]); } else { alert(name); // toString or something else } } 使用 hasOwnProperty 作为属性名节 JavaScript 并没有保护 hasOwnProperty 属性名,因此某个对象是有可能存在使用这个属性名的属性,使用外部的 hasOwnProperty 获得正确的结果是需要的:⚠️ var foo = { hasOwnProperty: function() { return false; }, bar: 'Here be dragons' }; foo.hasOwnProperty('bar'); // 始终返回 false // 如果担心这种情况,可以直接使用原型链上真正的 hasOwnProperty 方法 ({}).hasOwnProperty.call(foo, 'bar'); // true // 也可以使用 Object 原型上的 hasOwnProperty 属性 Object.prototype.hasOwnProperty.call(foo, 'bar'); // true
5、isPrototypeOf()
方法用于测试一个对象是否存在于另一个对象的原型链上。
语法:prototypeObj.isPrototypeOf(object)
参数: object
在该对象的原型链上搜寻
返回值:Boolean
,表示调用对象是否在另一个对象的原型链上。
报错 TypeError
如果 prototypeObj
为 undefined 或 null,会抛出 TypeError
。
描述:isPrototypeOf()
方法允许你检查一个对象是否存在于另一个对象的原型链上。
本示例展示了 Baz.prototype, Bar.prototype, Foo.prototype 和 Object.prototype 在 baz 对象的原型链上: function Foo() {} function Bar() {} function Baz() {} Bar.prototype = Object.create(Foo.prototype); Baz.prototype = Object.create(Bar.prototype); var baz = new Baz(); console.log(Baz.prototype.isPrototypeOf(baz)); // true console.log(Bar.prototype.isPrototypeOf(baz)); // true console.log(Foo.prototype.isPrototypeOf(baz)); // true console.log(Object.prototype.isPrototypeOf(baz)); // true 如果你有段代码只在需要操作继承自一个特定的原型链的对象的情况下执行,同 instanceof 操作符一样 isPrototypeOf() 方法就会派上用场,例如,为了确保某些方法或属性将位于对象上。 例如,检查 baz 对象是否继承自 Foo.prototype: if (Foo.prototype.isPrototypeOf(baz)) { // do something safe }
6、Object.seal()
方法封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要可写就可以改变。
语法: Object.seal(obj)
参数:
obj
将要被密封的对象。
返回值: 被密封的对象。
描述:通常,一个对象是可扩展的(可以添加新的属性)。密封一个对象会让这个对象变的不能添加新属性,且所有已有属性会变的不可配置。属性不可配置的效果就是属性变的不可删除,以及一个数据属性不能被重新定义成为访问器属性,或者反之。但属性的值仍然可以修改。尝试删除一个密封对象的属性或者将某个密封对象的属性从数据属性转换成访问器属性,结果会静默失败或抛出TypeError
(在严格模式 中最常见的,但不唯一)。
不会影响从原型链上继承的属性。但 __proto__
( ) 属性的值也会不能修改。
返回被密封对象的引用。
示例:
var obj = { prop: function() {}, foo: 'bar' }; // New properties may be added, existing properties // may be changed or removed. obj.foo = 'baz'; obj.lumpy = 'woof'; delete obj.prop; var o = Object.seal(obj); o === obj; // true Object.isSealed(obj); // === true // Changing property values on a sealed object // still works. obj.foo = 'quux'; // But you can't convert data properties to accessors, // or vice versa. Object.defineProperty(obj, 'foo', { get: function() { return 'g'; } }); // throws a TypeError // Now any changes, other than to property values, // will fail. obj.quaxxor = 'the friendly duck'; // silently doesn't add the property delete obj.foo; // silently doesn't delete the property // ...and in strict mode such attempts // will throw TypeErrors. function fail() { 'use strict'; delete obj.foo; // throws a TypeError obj.sparky = 'arf'; // throws a TypeError } fail(); // Attempted additions through // Object.defineProperty will also throw. Object.defineProperty(obj, 'ohai', { value: 17 }); // throws a TypeError Object.defineProperty(obj, 'foo', { value: 'eit' }); // changes existing property value
注意:在ES5中,如果这个方法的参数不是一个(原始)对象,那么它将导致TypeError
。在ES2015中,非对象参数将被视为已被密封的普通对象,会直接返回它。
对比 Object.freeze(),
使用Object.freeze()
冻结的对象中的现有属性是不可变的。用Object.seal()
密封的对象可以改变其现有属性。