ホームページ > 記事 > ウェブフロントエンド > JSでのObjectオブジェクトの操作方法をいくつか解説した記事(共有)
前回の記事「JavaScriptのオブジェクトコピーメソッドを徹底分析(コード付き)」では、JSのオブジェクトコピーメソッドについて学びました。以下の記事ではJSにおけるObjectオブジェクトの操作方法をいくつか紹介しますので、見ていきましょう。
#javascriptObject
いくつかの効率的な操作方法
const object1 = { a: 1, b: 2, c: 3 }; const object2 = Object.assign({ c: 4, d: 5 }, object1); console.log(object2); // { a: 1, b: 2, c: 3 ,c: 4, d: 5 }Object.create() メソッドは、既存のオブジェクトを使用して新しいオブジェクトを作成し、新しく作成されたオブジェクトの
proto を提供します。
const person = { color: "red", sayName: function () { console.log(this.name); }, }; const m = Object.create(person); m.name = "chuchur"; m.sayName(); // chuchurObject.defineProperties()このメソッドは、オブジェクトの新しいプロパティを直接定義するか、既存のプロパティを変更して、オブジェクトを返します。
var obj = {}; Object.defineProperties(obj, { property1: { value: 1, writable: true, }, property2: { value: "Hello", writable: false, }, }); obj.property1 = 1; obj.property2 = 2; console.log(obj); // {property1: 1, property2: "Hello"}Object.defineProperty()このメソッドは、オブジェクトの新しいプロパティを直接定義するか、オブジェクトの既存のプロパティを変更して、オブジェクトを返します。
var o = {}; // 创建一个新对象 // 在对象中添加一个属性与数据描述符的示例 Object.defineProperty(o, "a", { value: 37, writable: true, enumerable: true, configurable: true, }); // 对象o拥有了属性a,值为37 // 在对象中添加一个属性与存取描述符的示例 var bValue; Object.defineProperty(o, "b", { get: function () { return bValue; }, set: function (newValue) { bValue = newValue; }, enumerable: true, configurable: true, }); o.b = 38; // 对象o拥有了属性b,值为38 // o.b的值现在总是与bValue相同,除非重新定义o.bObject.entries()このメソッドは、指定されたオブジェクト独自の列挙可能なプロパティのキーと値のペアの配列を返します。この配列は、
for...in に配置されて使用されます。オブジェクトをループするときに返される順序は同じです (違いは、
for-in ループがプロトタイプ チェーン内のプロパティも列挙することです)。
const obj = { foo: "bar", baz: 42 }; console.log(Object.entries(obj)); //[['foo','bar'],['baz',42]]Object.keys()このメソッドは、指定されたオブジェクトの自己列挙可能なプロパティで構成される配列を返します。配列内のプロパティ名の順序と # の使用##for ...in
オブジェクトをループするときに返される順序は一貫しています。 <pre class="brush:php;toolbar:false">// simple array
var arr = ["a", "b", "c"];
console.log(Object.keys(arr)); // console: [&#39;0&#39;, &#39;1&#39;, &#39;2&#39;]
// array like object
var obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.keys(obj)); // console: [&#39;0&#39;, &#39;1&#39;, &#39;2&#39;]
// array like object with random key ordering
var anObj = { 100: "a", 2: "b", 7: "c" };
console.log(Object.keys(anObj)); // console: [&#39;2&#39;, &#39;7&#39;, &#39;100&#39;]
// getFoo is a property which isn&#39;t enumerable
var myObj = Object.create(
{},
{
getFoo: {
value: function () {
return this.foo;
},
},
}
);
myObj.foo = 1;
console.log(Object.keys(myObj)); // console: [&#39;foo&#39;]</pre>
Object.values()
ループの順序は同じです (違いは、for-in
ループがプロトタイプ チェーン内のプロパティを列挙することです)。 <pre class="brush:php;toolbar:false">var obj = { foo: "bar", baz: 42 };
console.log(Object.values(obj)); // [&#39;bar&#39;, 42]
// array like object
var obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.values(obj)); // [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;]
// array like object with random key ordering
// when we use numeric keys, the value returned in a numerical order according to the keys
var an_obj = { 100: "a", 2: "b", 7: "c" };
console.log(Object.values(an_obj)); // [&#39;b&#39;, &#39;c&#39;, &#39;a&#39;]
// getFoo is property which isn&#39;t enumerable
var my_obj = Object.create(
{},
{
getFoo: {
value: function () {
return this.foo;
},
},
}
);
my_obj.foo = "bar";
console.log(Object.values(my_obj)); // [&#39;bar&#39;]
// non-object argument will be coerced to an object
console.log(Object.values("foo")); // [&#39;f&#39;, &#39;o&#39;, &#39;o&#39;] ==Array.from(&#39;foo&#39;)
//ES5
if (!Object.values)
Object.values = function (obj) {
if (obj !== Object(obj))
throw new TypeError("Object.values called on a non-object");
var val = [],
key;
for (key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
val.push(obj[key]);
}
}
return val;
};</pre>
Object.hasOwnProperty()
o = new Object(); o.prop = "exists"; function changeO() { o.newprop = o.prop; delete o.prop; } o.hasOwnProperty("prop"); // 返回 true changeO(); o.hasOwnProperty("prop"); // 返回 false o.hasOwnProperty("toString"); // 返回 false o.hasOwnProperty("hasOwnProperty"); // 返回 false
Object.getOwnPropertyDescriptor()
o = { bar: 42 }; d = Object.getOwnPropertyDescriptor(o, "bar"); // d { // configurable: true, // enumerable: true, // value: 42, // writable: true // }
Object.getOwnPropertyDescriptors()
Object.create( Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj) );Object.getOwnPropertyNames()
var arr = ["a", "b", "c"]; console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"] // 类数组对象 var obj = { 0: "a", 1: "b", 2: "c" }; console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"] // 使用Array.forEach输出属性名和属性值 Object.getOwnPropertyNames(obj).forEach(function (val, idx, array) { console.log(val + " -> " + obj[val]); }); // 输出 // 0 -> a // 1 -> b // 2 -> c //不可枚举属性 var my_obj = Object.create( {}, { getFoo: { value: function () { return this.foo; }, enumerable: false, }, } ); my_obj.foo = 1; console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]
Object.getOwnPropertySymbols()
メソッドは、指定されたオブジェクト自体のすべての 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); // 2 console.log(objectSymbols); // [Symbol(a), Symbol(b)] console.log(objectSymbols[0]); // Symbol(a)
Object.isPrototypeOf()
このメソッドは、オブジェクトが別のオブジェクトのプロトタイプ チェーン上に存在するかどうかをテストするために使用されます。 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
var o = {}; var a = []; o.prop = "is enumerable"; a[0] = "is enumerable"; o.propertyIsEnumerable("prop"); // 返回 true a.propertyIsEnumerable(0); // 返回 true //用户自定义对象和引擎内置对象 var a = ["is enumerable"]; a.propertyIsEnumerable(0); // 返回 true a.propertyIsEnumerable("length"); // 返回 false Math.propertyIsEnumerable("random"); // 返回 false this.propertyIsEnumerable("Math"); // 返回 false //自身属性和继承属性 var a = []; a.propertyIsEnumerable("constructor"); // 返回 false function firstConstructor() { this.property = "is not enumerable"; } firstConstructor.prototype.firstMethod = function () {}; function secondConstructor() { this.method = function method() { return "is enumerable"; }; } secondConstructor.prototype = new firstConstructor(); secondConstructor.prototype.constructor = secondConstructor; var o = new secondConstructor(); o.arbitraryProperty = "is enumerable"; o.propertyIsEnumerable("arbitraryProperty"); // 返回 true o.propertyIsEnumerable("method"); // 返回 true o.propertyIsEnumerable("property"); // 返回 false o.property = "is enumerable"; o.propertyIsEnumerable("property"); // 返回 true // 这些返回fasle,是因为,在原型链上propertyIsEnumerable不被考虑 // (尽管最后两个在for-in循环中可以被循环出来)。 o.propertyIsEnumerable("prototype"); // 返回 false (根据 JS 1.8.1/FF3.6) o.propertyIsEnumerable("constructor"); // 返回 false o.propertyIsEnumerable("firstMethod"); // 返回 false
const prototype1 = {}; const object1 = Object.create(prototype1); console.log(Object.getPrototypeOf(object1) === prototype1); // expected output: true
Object.is を返します。指定されたオブジェクトの ()
メソッドは、2 つの値が同じ値であるかどうかを判断します。 Object.is("foo", "foo"); // true Object.is(window, window); // true Object.is("foo", "bar"); // false Object.is([], []); // false var test = { a: 1 }; Object.is(test, test); // true Object.is(null, null); // true // 特例 Object.is(0, -0); // false Object.is(-0, -0); // true Object.is(NaN, 0 / 0); // true // ES5 if (!Object.is) { Object.is = function (x, y) { // SameValue algorithm if (x === y) { // Steps 1-5, 7-10 // Steps 6.b-6.e: +0 != -0 return x !== 0 || 1 / x === 1 / y; } else { // Step 6.a: NaN == NaN return x !== x && y !== y; } }; }
// 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异常
// 新对象默认是可扩展的. 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
const object1 = { property1: 42, }; const object2 = Object.freeze(object1); object2.property1 = 33; // 严格模式会报错,非严格模式不报错,但是不执行 console.log(object2.property1); // 输出: 42
// 使用Object.freeze是冻结一个对象最方便的方法. var frozen = { 1: 81 }; Object.isFrozen(frozen); //=== false Object.freeze(frozen); Object.isFrozen(frozen); //=== true // 一个冻结对象也是一个密封对象. Object.isSealed(frozen); //=== true // 当然,更是一个不可扩展的对象. Object.isExtensible(frozen); //=== false // 一个对象默认是可扩展的,所以它也是非冻结的. Object.isFrozen({}); // === false // 一个不可扩展的空对象同时也是一个冻结对象. var vacuouslyFrozen = Object.preventExtensions({}); Object.isFrozen(vacuouslyFrozen); //=== true; // 一个非空对象默认也是非冻结的. var oneProp = { p: 42 }; Object.isFrozen(oneProp); //=== false // 让这个对象变的不可扩展,并不意味着这个对象变成了冻结对象, // 因为p属性仍然是可以配置的(而且可写的). Object.preventExtensions(oneProp); Object.isFrozen(oneProp); //=== false // ...如果删除了这个属性,则它会成为一个冻结对象. delete oneProp.p; Object.isFrozen(oneProp); //=== true // 一个不可扩展的对象,拥有一个不可写但可配置的属性,则它仍然是非冻结的. var nonWritable = { e: "plep" }; Object.preventExtensions(nonWritable); Object.defineProperty(nonWritable, "e", { writable: false }); // 变得不可写 Object.isFrozen(nonWritable); //=== false // 把这个属性改为不可配置,会让这个对象成为冻结对象. Object.defineProperty(nonWritable, "e", { configurable: false }); // 变得不可配置 Object.isFrozen(nonWritable); //=== true // 一个不可扩展的对象,拥有一个不可配置但可写的属性,则它仍然是非冻结的. var nonConfigurable = { release: "the kraken!" }; Object.preventExtensions(nonConfigurable); Object.defineProperty(nonConfigurable, "release", { configurable: false }); Object.isFrozen(nonConfigurable); //=== false // 把这个属性改为不可写,会让这个对象成为冻结对象. Object.defineProperty(nonConfigurable, "release", { writable: false }); Object.isFrozen(nonConfigurable); //=== true // 一个不可扩展的对象,值拥有一个访问器属性,则它仍然是非冻结的. var accessor = { get food() { return "yum"; }, }; Object.preventExtensions(accessor); Object.isFrozen(accessor); //=== false // ...但把这个属性改为不可配置,会让这个对象成为冻结对象. Object.defineProperty(accessor, "food", { configurable: false }); Object.isFrozen(accessor); //=== true
const object1 = { property1: 42, }; Object.seal(object1); object1.property1 = 33; console.log(object1.property1); // expected output: 33 delete object1.property1; // cannot delete when sealed console.log(object1.property1); // expected output: 33
// 新建的对象默认不是密封的. var empty = {}; Object.isSealed(empty); // === false // 如果你把一个空对象变的不可扩展,则它同时也会变成个密封对象. Object.preventExtensions(empty); Object.isSealed(empty); // === true // 但如果这个对象不是空对象,则它不会变成密封对象,因为密封对象的所有自身属性必须是不可配置的. var hasProp = { fee: "fie foe fum" }; Object.preventExtensions(hasProp); Object.isSealed(hasProp); // === false // 如果把这个属性变的不可配置,则这个对象也就成了密封对象. Object.defineProperty(hasProp, "fee", { configurable: false }); Object.isSealed(hasProp); // === true // 最简单的方法来生成一个密封对象,当然是使用Object.seal. var sealed = {}; Object.seal(sealed); Object.isSealed(sealed); // === true // 一个密封对象同时也是不可扩展的. Object.isExtensible(sealed); // === false // 一个密封对象也可以是一个冻结对象,但不是必须的. Object.isFrozen(sealed); // === true ,所有的属性都是不可写的 var s2 = Object.seal({ p: 3 }); Object.isFrozen(s2); // === false, 属性"p"可写 var s3 = Object.seal({ get p() { return 0; }, }); Object.isFrozen(s3); // === true ,访问器属性不考虑可写不可写,只考虑是否可配置
// Array:返回数组对象本身 var array = ["ABC", true, 12, -5]; console.log(array.valueOf() === array); // true // Date:当前时间距1970年1月1日午夜的毫秒数 var date = new Date(2013, 7, 18, 23, 11, 59, 230); console.log(date.valueOf()); // 1376838719230 // Number:返回数字值 var num = 15.2654; console.log(num.valueOf()); // 15.2654 // 布尔:返回布尔值true或false var bool = true; console.log(bool.valueOf() === bool); // true // new一个Boolean对象 var newBool = new Boolean(true); // valueOf()返回的是true,两者的值相等 console.log(newBool.valueOf() == newBool); // true // 但是不全等,两者类型不相等,前者是boolean类型,后者是object类型 console.log(newBool.valueOf() === newBool); // false // Function:返回函数本身 function foo() {} console.log(foo.valueOf() === foo); // true var foo2 = new Function("x", "y", "return x + y;"); console.log(foo2.valueOf()); /* ƒ anonymous(x,y ) { return x + y; } */ // Object:返回对象本身 var obj = { name: "张三", age: 18 }; console.log(obj.valueOf() === obj); // true // String:返回字符串值 var str = "http://www.xyz.com"; console.log(str.valueOf() === str); // true // new一个字符串对象 var str2 = new String("http://www.xyz.com"); // 两者的值相等,但不全等,因为类型不同,前者为string类型,后者为object类型 console.log(str2.valueOf() === str2); // false
JavaScript ビデオ チュートリアル
以上がJSでのObjectオブジェクトの操作方法をいくつか解説した記事(共有)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。