属性
Object.prototype.value:设置属性的值
Object.prototype.writable:是否可修改属性的值;默认为false
Object.prototype.enumerable:是否可枚举属性;默认为false
Object.prototype.configurable:是否可修改属性的特性;默认为false
对象创建
Object.create(prototype[,propertiesObject])
使用指定的原型对象及其属性去创建一个新的对象。
var parent = { x : 1, y : 1 } var child = Object.create(parent,{ z : { // z会成为创建对象的属性 writable:true, configurable:true, value: "newAdd" } }); console.log(child); //{z: "newAdd"} console.log(hild.__proto__); //{x: 1, y: 1}
对象属性操作
Object.defineProperty(obj, prop, descriptor)
在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
obj:必需。目标对象 prop:必需。需定义或修改的属性的名字 descriptor:必需。将被定义或修改的属性的描述符 返回值: 传入函数的对象。即第一个参数obj
var obj = { test:"hello" } Object.defineProperty(obj,"haha",{ configurable: true, enumerable: true, value: "kkk", writable: true }); // { haha: "kkk" test: "hello" }
属性描述符
对象里目前存在的属性描述符有两种主要形式:
- 数据描述符: 一个拥有可写或不可写值的属性
- 存取描述符: 由一对 getter-setter 函数功能来描述的属性
描述符必须是两种形式之一;不能同时是两者。
数据描述符和存取描述符均具有以下可选键值:
configurable true,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。 enumerable true,该属性才能够出现在对象的枚举属性中。默认为 false。
数据描述符同时具有以下可选键值:
value 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。 writable true,该属性才能被赋值运算符改变。默认为 false。
存取描述符同时具有以下可选键值:
get 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined。 set 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined。
// get & set var obj = {}; var initValue = 'hello'; Object.defineProperty(obj,"newKey",{ get:function (){ return initValue; }, set:function (value){ initValue = value; } }); obj.newKey //"hello" obj.newKey = "haha"; //"haha" obj.newKey //"haha" // set var obj1 = {}; var initValue1 = 'hello'; Object.defineProperty(obj1,"newKey",{ set:function (value){ initValue1 = value; } }); obj1.newKey //undefined obj1.newKey = "haha"; //"haha" obj1.newKey //undefined // get var obj2 = {}; var initValue2 = 'hello'; Object.defineProperty(obj2,"newKey",{ get:function (){ return initValue2; }, }); obj2.newKey //"hello" obj2.newKey = "haha"; //"haha" obj2.newKey //"hello"
Object.defineProperties(obj, props)
直接在一个对象上定义新的属性或修改现有属性,并返回该对象。
var obj = {}; Object.defineProperties(obj, { 'property1': { value: true, writable: true }, 'property2': { value: 'Hello', writable: false } }); console.log(obj) // {property1: true, property2: "Hello"}
Object.getOwnPropertyDescriptor(obj,prop)
返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)。
如果指定的属性存在于对象上,则返回其属性描述符对象(property descriptor),否则返回 undefined。
Object.getOwnPropertyDescriptors(obj)
获取一个对象的所有自身属性的描述符。
var obj = { name : 'js', age : 20 } console.log(Object.getOwnPropertyDescriptors(obj)); // {name: {…}, age: {…}} // age: {value: 20, writable: true, enumerable: true, configurable: true} // name: {value: "js", writable: true, enumerable: true, configurable:true}
Object.getOwnPropertyNames()
返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
var obj = { 0: "a", 1: "b", 2: "c"}; Object.getOwnPropertyNames(obj); //["0", "1", "2"]
Object.getOwnPropertySymbols()
返回一个给定对象自身的所有 Symbol 属性的数组。
Object.preventExtensions()
对象不能再添加新的属性。可修改,删除现有属性,不能添加新属性。
var obj = { name :'lilei', age : 30 , sex : 'male' } obj = Object.preventExtensions(obj); //{name: "lilei", age: 30, sex: "male"} obj.name = "hanmeimei"; //{name: "hanmeimei", age: 30, sex: "male"} obj.cc = "ee"; //{name: "hanmeimei", age: 30, sex: "male"}
Object.keys(obj)
返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 (两者的主要区别是 for-in 循环还会枚举其原型链上的属性)。
var obj = { foo: "bar", baz: 42 }, keys = Object.keys(obj); console.log(keys); //["foo", "baz"]
Object.keys排列顺序:
- 如果key是整数或者整数类型的字符串,那么会按从小到大的排序(排在其它数据类型前面);
- 其它数据类型,按照实际创建顺序排序;
1. integer 2. normal key 3. symbol
Object.values()
方法返回一个给定对象自己的所有可枚举属性值的数组,值的顺序与使用for...in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。
Object.values会过滤属性名为 Symbol 值的属性。
var an_obj = { 100: 'a', 2: 'b', 7: 'c' }; console.log(Object.values(an_obj)); //["b", "c", "a"]
Object.entries()
返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环也枚举原型链中的属性)。
var obj = { foo: 'bar', baz: 42 }; console.log(Object.entries(obj)); //[Array(2), Array(2)] // [["foo", "bar"], ["baz", 42]]
其他静态方法
Object.assign(target,source1,source2,...)
该方法主要用于对象的合并,将源对象source的所有可枚举属性合并到目标对象target上,此方法只拷贝源对象的自身属性,不拷贝继承的属性。
const target = { x : 0, y : 1 }; const source = { x : 1, z : 2 , fn : { number : 1 } }; Object.assign(target, source); // target {x : 1, y : 1, z : 2, fn : {number : 1}} 同名属性会被覆盖 // source {x : 1, z : 2, fn : {number : 1}}
Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。同名属性会替换。
Object.getPrototypeOf()
返回指定对象的原型(内部[[Prototype]]属性的值,即__proto__,而非对象的prototype)。
Object.isPrototypeOf()
判断一个对象是否存在于另一个对象的原型链上。
Object.setPrototypeOf(obj,prototype)
设置对象的原型对象
Object.is()
判断两个值是否相同。
如果下列任何一项成立,则两个值相同:
- 两个值都是 undefined
- 两个值都是 null
- 两个值都是 true 或者都是 false
- 两个值是由相同个数的字符按照相同的顺序组成的字符串
- 两个值指向同一个对象
- 两个值都是数字并且
- 都是正零 +0
- 都是负零 -0
- 都是 NaN
- 都是除零和 NaN 外的其它同一个数字
Object.is([], []); // false
Object.freeze()
冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象。
var obj = { prop: function() {}, foo: 'bar' }; Object.freeze(obj); //{prop: ƒ, foo: "bar"} obj.foo = 'eee'; console.log(obj); //{prop: ƒ, foo: "bar"}
Object.isFrozen()
判断一个对象是否被冻结。
Object.isExtensible()
判断对象是否是可扩展的,Object.preventExtensions,Object.seal 或 Object.freeze 方法都可以标记一个对象为不可扩展(non-extensible)。
Object.seal()
Object.seal() 方法可以让一个对象密封,并返回被密封后的对象。密封一个对象会让这个对象变的不能添加新属性,且所有已有属性会变的不可配置。属性不可配置的效果就是属性变的不可删除,以及一个数据属性不能被重新定义成为访问器属性,或者反之。但属性的值仍然可以修改。尝试删除一个密封对象的属性或者将某个密封对象的属性从数据属性转换成访问器属性,结果会静默失败或抛出TypeError 异常. 不会影响从原型链上继承的属性。但 proto ( ) 属性的值也会不能修改。
Object.isSealed()
判断一个对象是否被密封。
实例方法
hasOwnProperty(propertyName)
判断对象是否拥有一个指定名称的实例属性(非继承)
参数:
①propertyName {string} :属性名称。
返回值:
{bool} 判断对象是否拥有一个指定名称的本地定义(非继承)的属性;此方法不会检查对象原型链中的属性。
true :属性为对象的实例属性,非继承。
false :属性不为对象的实例属性。
var o = new Object(); o.name = 'kkkk'; // 定义一个实例属性 console.log(o.hasOwnProperty('name')); // => true:name属性为实例o自己定义的,而非继承 console.log(o.hasOwnProperty('toString')); // => false:toString为继承属性
isPrototypeOf(obejct)
判断某个原型是否出现在对象的原型链中
语法:
prototype.isPrototypeOf(object)
参数:
①obejct {object} :被检测的对象。
返回值:
{bool} 返回某个原型是否出现在对象的原型链中
true :是
false :不是
var array = [1, 2, 3]; console.log(Array.prototype.isPrototypeOf(array)); // => true :数组原型 console.log(Object.prototype.isPrototypeOf(array)); // => true :Object是所有对象的基原型
propertyIsEnumerable(propertyName)
判断指定名称的属性是否为实例属性并且是可枚举的(可用for/in循环枚举)
参数:
①propertyName {string} :属性名称
返回值:
{bool} 判断属性是否为实例属性并且是可枚举的(可用for/in循环枚举),不考虑原型链中的成员。
true :是
false :不是
var array = [1, 2, 3]; array.name = 'Array'; console.log(array.propertyIsEnumerable('name')); // => true :name属性为实例属性 console.log(array.propertyIsEnumerable('join')); // => false :join方法继承自Array console.log(array.propertyIsEnumerable('length')); // => false :length属性继承自Array console.log(array.propertyIsEnumerable('toString')); // => false :toString方法继承自Object