JavaScript中Object对象方法超详细讲解举例说明仅此一篇
在JavaScript中,几乎所有的对象都是Object 类型的实例,它们都会从Object.prototype 继承属性和方法。Object 构造函数为给定值创建一个对象包装器。Object 构造函数,会根据给定的参数创建对象。
- 如果给定值是
null 或 undefined ,将会创建并返回一个空对象 - 如果传进去的是一个基本类型的值,则会构造其包装类型的对象
- 如果传进去的是引用类型的值,仍然会返回这个值,经他们复制的变量保有和源对象相同的引用地址
Object.assign()
Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。
语法
Object.assign(target, ...sources)
参数
-
target 目标对象。 -
sources 源对象。
返回值
例子
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
console.log(returnedTarget);
Object.create()
Object.create() 方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
语法
Object.create(proto,[propertiesObject])
参数
返回值
例子
const person = {
isHuman: false,
printIntroduction: function() {
console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
}
};
const me = Object.create(person);
me.name = 'Matthew';
me.isHuman = true;
me.printIntroduction();
Object.values()
Object.values() 方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for...in 循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。
语法
Object.values(obj)
参数
返回值
描述
Object.values() 返回一个数组,其元素是在对象上找到的可枚举属性值。属性的顺序与通过手动循环对象的属性值所给出的顺序相同。
例子
var obj = { foo: 'bar', baz: 42 };
console.log(Object.values(obj));
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj));
var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.values(an_obj));
var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
my_obj.foo = 'bar';
console.log(Object.values(my_obj));
console.log(Object.values('foo'));
Object.entries()
Object.entries() 方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。
语法
Object.entries(obj)
参数
返回值
例子
const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj));
const obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(obj));
const anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.entries(anObj));
const myObj = Object.create({}, { getFoo: { value() { return this.foo; } } });
myObj.foo = 'bar';
console.log(Object.entries(myObj));
console.log(Object.entries('foo'));
const obj = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {
console.log(`${key} ${value}`);
}
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key} ${value}`);
});
例子
const object1 = {
a: 'somestring',
b: 42
};
for (const [key, value] of Object.entries(object1)) {
console.log(`${key}: ${value}`);
}
Object.freeze()
Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。
语法
Object.freeze(obj)
参数
返回值
例子
冻结对象
var obj = {
prop: function() {},
foo: 'bar'
};
obj.foo = 'baz';
obj.lumpy = 'woof';
delete obj.prop;
var o = Object.freeze(obj);
o === obj;
Object.isFrozen(obj);
obj.foo = 'quux';
obj.quaxxor = 'the friendly duck';
function fail(){
'use strict';
obj.foo = 'sparky';
delete obj.quaxxor;
obj.sparky = 'arf';
}
fail();
Object.defineProperty(obj, 'ohai', { value: 17 });
Object.defineProperty(obj, 'foo', { value: 'eit' });
Object.setPrototypeOf(obj, { x: 20 })
obj.__proto__ = { x: 20 }
冻结数组
let a = [0];
Object.freeze(a);
a[0]=1;
a.push(2);
function fail() {
"use strict"
a[0] = 1;
a.push(2);
}
fail();
被冻结的对象是不可变的。但也不总是这样。下例展示了冻结对象不是常量对象(浅冻结)。
obj1 = {
internal: {}
};
Object.freeze(obj1);
obj1.internal.a = 'aValue';
obj1.internal.a
对于一个常量对象,整个引用图(直接和间接引用其他对象)只能引用不可变的冻结对象。冻结的对象被认为是不可变的,因为整个对象中的整个对象状态(对其他对象的值和引用)是固定的。注意,字符串,数字和布尔总是不可变的,而函数和数组是对象。
要使对象不可变,需要递归冻结每个类型为对象的属性(深冻结)。当你知道对象在引用图中不包含任何 环 (循环引用)时,将根据你的设计逐个使用该模式,否则将触发无限循环。对 deepFreeze() 的增强将是具有接收路径(例如Array)参数的内部函数,以便当对象进入不变时,可以递归地调用 deepFreeze() 。你仍然有冻结不应冻结的对象的风险,例如[window]。
function deepFreeze(obj) {
var propNames = Object.getOwnPropertyNames(obj);
propNames.forEach(function(name) {
var prop = obj[name];
if (typeof prop == 'object' && prop !== null)
deepFreeze(prop);
});
return Object.freeze(obj);
}
obj2 = {
internal: {}
};
deepFreeze(obj2);
obj2.internal.a = 'anotherValue';
obj2.internal.a;
Object.fromEntries()
Object.fromEntries() 方法把键值对列表转换为一个对象。
语法
Object.fromEntries(iterable);
参数
返回值
示例
Map 转化为 Object
通过 Object.fromEntries , 可以将 Map 转换为 Object :
const map = new Map([ ['foo', 'bar'], ['baz', 42] ]);
const obj = Object.fromEntries(map);
console.log(obj); // { foo: "bar", baz: 42 }
Array 转化为 Object
通过 Object.fromEntries , 可以将 Array 转换为 Object :
const arr = [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ];
const obj = Object.fromEntries(arr);
console.log(obj); // { 0: "a", 1: "b", 2: "c" }
对象转换
Object.fromEntries 是与 Object.entries() 相反的方法,用 数组处理函数 可以像下面这样转换对象:
const object1 = { a: 1, b: 2, c: 3 };
const object2 = Object.fromEntries(
Object.entries(object1)
.map(([ key, val ]) => [ key, val * 2 ])
);
console.log(object2);
// { a: 2, b: 4, c: 6 }
Object.is()
Object.is() 方法判断两个值是否为同一个值。
语法
Object.is(value1, value2);
参数
-
value1 被比较的第一个值。 -
value2 被比较的第二个值。
返回值
- 一个
Boolean 类型标示两个参数是否是同一个值。
例子
Object.keys()
Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。
语法
Object.keys(obj)
参数
返回值
例子
var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr));
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj));
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj));
var myObj = Object.create({}, {
getFoo: {
value: function () { return this.foo; }
}
});
myObj.foo = 1;
console.log(Object.keys(myObj));
如果你想获取一个对象的所有属性,,甚至包括不可枚举的,请查看Object.getOwnPropertyNames 。
Object.values()
Object.values() 方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for...in 循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。
语法
Object.values(obj)
参数
返回值
示例
var obj = { foo: 'bar', baz: 42 };
console.log(Object.values(obj));
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj));
var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.values(an_obj));
var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
my_obj.foo = 'bar';
console.log(Object.values(my_obj));
console.log(Object.values('foo'));
Object.seal()
Object.seal() 方法封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要原来是可写的就可以改变。
语法
Object.seal(obj)
参数
返回值
例子
var obj = {
prop: function() {},
foo: 'bar'
};
obj.foo = 'baz';
obj.lumpy = 'woof';
delete obj.prop;
var o = Object.seal(obj);
o === obj;
Object.isSealed(obj);
obj.foo = 'quux';
Object.defineProperty(obj, 'foo', {
get: function() { return 'g'; }
});
obj.quaxxor = 'the friendly duck';
delete obj.foo;
function fail() {
'use strict';
delete obj.foo;
obj.sparky = 'arf';
}
fail();
Object.defineProperty(obj, 'ohai', {
value: 17
});
Object.defineProperty(obj, 'foo', {
value: 'eit'
});
Object.defineProperties()
Object.defineProperties() 方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。
语法
Object.defineProperties(obj, props)
参数
-
obj 在其上定义或修改属性的对象。 -
props 要定义其可枚举属性或修改的属性描述符的对象。对象中存在的属性描述符主要有两种:数据描述符和访问器描述符(更多详情,请参阅Object.defineProperty() )。描述符具有以下键: configurable``true 只有该属性描述符的类型可以被改变并且该属性可以从对应对象中删除。 默认为 false``enumerable``true 只有在枚举相应对象上的属性时该属性显现。 默认为 false``value 与属性关联的值。可以是任何有效的JavaScript值(数字,对象,函数等)。 默认为 undefined .writable``true 只有与该属性相关联的值被assignment operator (en-US)改变时。 默认为 false``get 作为该属性的 getter 函数,如果没有 getter 则为undefined 。函数返回值将被用作属性的值。 默认为 undefined``set 作为属性的 setter 函数,如果没有 setter 则为undefined 。函数将仅接受参数赋值给该属性的新值。 默认为 undefined
返回值
例子
var obj = {};
Object.defineProperties(obj, {
'property1': {
value: true,
writable: true
},
'property2': {
value: 'Hello',
writable: false
}
});
Object.defineProperty()
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
语法
Object.defineProperty(obj, prop, descriptor)
参数
-
obj 要定义属性的对象。 -
prop 要定义或修改的属性的名称或 Symbol 。 -
descriptor 要定义或修改的属性描述符。
返回值
例子
const object1 = {};
Object.defineProperty(object1, 'property1', {
value: 42,
writable: false
});
object1.property1 = 77;
console.log(object1.property1);
Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor() 方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)
语法
Object.getOwnPropertyDescriptor(obj, prop)
参数
-
obj 需要查找的目标对象 -
prop 目标对象内属性名称
返回值
- 如果指定的属性存在于对象上,则返回其属性描述符对象(property descriptor),否则返回
undefined 。
例子
var o, d;
o = { get foo() { return 17; } };
d = Object.getOwnPropertyDescriptor(o, "foo");
o = { bar: 42 };
d = Object.getOwnPropertyDescriptor(o, "bar");
o = {};
Object.defineProperty(o, "baz", {
value: 8675309,
writable: false,
enumerable: false
});
d = Object.getOwnPropertyDescriptor(o, "baz");
Object.getOwnPropertyDescriptors()
Object.getOwnPropertyDescriptors() 方法用来获取一个对象的所有自身属性的描述符。
语法
Object.getOwnPropertyDescriptors(obj)
参数
返回值
- 所指定对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象。
例子
浅拷贝一个对象
Object.assign() 方法只能拷贝源对象的可枚举的自身属性,同时拷贝时无法拷贝属性的特性们,而且访问器属性会被转换成数据属性,也无法拷贝源对象的原型,该方法配合 Object.create() 方法可以实现上面说的这些。
Object.create(
Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj)
);
创建子类
创建子类的典型方法是定义子类,将其原型设置为超类的实例,然后在该实例上定义属性。这么写很不优雅,特别是对于 getters 和 setter 而言。 相反,您可以使用此代码设置原型:
function superclass() {}
superclass.prototype = {
};
function subclass() {}
subclass.prototype = Object.create(superclass.prototype, Object.getOwnPropertyDescriptors({
}));
Object.getOwnPropertyNames()
Object.getOwnPropertyNames() 方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
语法
Object.getOwnPropertyNames(obj)
参数
返回值
例子
使用 Object.getOwnPropertyNames()
var arr = ["a", "b", "c"];
console.log(Object.getOwnPropertyNames(arr).sort());
var obj = { 0: "a", 1: "b", 2: "c"};
console.log(Object.getOwnPropertyNames(obj).sort());
Object.getOwnPropertyNames(obj).forEach(function(val, idx, array) {
console.log(val + " -> " + obj[val]);
});
var my_obj = Object.create({}, {
getFoo: {
value: function() { return this.foo; },
enumerable: false
}
});
my_obj.foo = 1;
console.log(Object.getOwnPropertyNames(my_obj).sort());
如果你只要获取到可枚举属性,查看Object.keys 或用for...in 循环(还会获取到原型链上的可枚举属性,不过可以使用hasOwnProperty() 方法过滤掉)。
下面的例子演示了该方法不会获取到原型链上的属性:
function ParentClass() {}
ParentClass.prototype.inheritedMethod = function() {};
function ChildClass() {
this.prop = 5;
this.method = function() {};
}
ChildClass.prototype = new ParentClass;
ChildClass.prototype.prototypeMethod = function() {};
console.log(
Object.getOwnPropertyNames(
new ChildClass()
)
);
只获取不可枚举的属性
下面的例子使用了 Array.prototype.filter() 方法,从所有的属性名数组(使用Object.getOwnPropertyNames() 方法获得)中去除可枚举的属性(使用Object.keys() 方法获得),剩余的属性便是不可枚举的属性了:
var target = myObject;
var enum_and_nonenum = Object.getOwnPropertyNames(target);
var enum_only = Object.keys(target);
var nonenum_only = enum_and_nonenum.filter(function(key) {
var indexInEnum = enum_only.indexOf(key);
if (indexInEnum == -1) {
return true;
} else {
return false;
}
});
console.log(nonenum_only);
注:Array.filter(filt_func)方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
Object.getOwnPropertySymbols()
Object.getOwnPropertySymbols() 方法返回一个给定对象自身的所有 Symbol 属性的数组。
语法
Object.getOwnPropertySymbols(obj)
参数
返回值
- 在给定对象自身上找到的所有 Symbol 属性的数组。
例子
var obj = {};
var a = Symbol("a");
var b = Symbol.for("b");
obj[a] = "localSymbol";
obj[b] = "globalSymbol";
var objectSymbols = Object.getOwnPropertySymbols(obj);
console.log(objectSymbols.length);
console.log(objectSymbols)
console.log(objectSymbols[0])
Object.getPrototypeOf()
Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]] 属性的值)。
语法
Object.getPrototypeOf(object)
参数
返回值
- 给定对象的原型。如果没有继承属性,则返回
null 。
例子
const prototype1 = {};
const object1 = Object.create(prototype1);
console.log(Object.getPrototypeOf(object1) === prototype1);
参考地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object
|