Dans l'article précédent "Analyse approfondie de la méthode de copie d'objet en JavaScript (avec code)", nous avons découvert la méthode de copie d'objet en JS. L'article suivant vous présentera quelques méthodes de fonctionnement des objets Object dans JS. Jetons un coup d'œil.
Certaines méthodes de fonctionnement efficaces de Object
en javascript
javascript
中Object
一些高效的操作方法
方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
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 }
方法创建一个新对象,使用现有的对象来提供新创建的对象的proto
。
const person = { color: "red", sayName: function () { console.log(this.name); }, }; const m = Object.create(person); m.name = "chuchur"; m.sayName(); // chuchur
方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。
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"}
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回这个对象。
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.b
方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用for...in
循环遍历该对象时返回的顺序一致(区别在于for-in
循环也枚举原型链中的属性)。
const obj = { foo: "bar", baz: 42 }; console.log(Object.entries(obj)); //[['foo','bar'],['baz',42]]
方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用for...in
循环遍历该对象时返回的顺序一致 。
// simple array var arr = ["a", "b", "c"]; console.log(Object.keys(arr)); // console: ['0', '1', '2'] // array like object var obj = { 0: "a", 1: "b", 2: "c" }; console.log(Object.keys(obj)); // console: ['0', '1', '2'] // array like object with random key ordering var anObj = { 100: "a", 2: "b", 7: "c" }; console.log(Object.keys(anObj)); // console: ['2', '7', '100'] // getFoo is a property which isn't enumerable var myObj = Object.create( {}, { getFoo: { value: function () { return this.foo; }, }, } ); myObj.foo = 1; console.log(Object.keys(myObj)); // console: ['foo']
方法返回一个给定对象自己的所有可枚举属性值的数组,值的顺序与使用for...in
循环的顺序相同(区别在于for-in
循环枚举原型链中的属性 )。
var obj = { foo: "bar", baz: 42 }; console.log(Object.values(obj)); // ['bar', 42] // array like object var obj = { 0: "a", 1: "b", 2: "c" }; console.log(Object.values(obj)); // ['a', 'b', 'c'] // 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)); // ['b', 'c', 'a'] // getFoo is property which isn't enumerable var my_obj = Object.create( {}, { getFoo: { value: function () { return this.foo; }, }, } ); my_obj.foo = "bar"; console.log(Object.values(my_obj)); // ['bar'] // non-object argument will be coerced to an object console.log(Object.values("foo")); // ['f', 'o', 'o'] ==Array.from('foo') //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; };
方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性。
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
方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)
o = { bar: 42 }; d = Object.getOwnPropertyDescriptor(o, "bar"); // d { // configurable: true, // enumerable: true, // value: 42, // writable: true // }
方法用来获取一个对象的所有自身属性的描述符。
Object.assign()方法只能拷贝源对象的可枚举的自身属性,同时拷贝时无法拷贝属性的特性们,而且访问器属性会被转换成数据属性,也无法拷贝源对象的原型,该方法配合Object.create() 方法可以实现上面说的这些。
Object.create( Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj) );
方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol
值作为名称的属性)组成的数组。
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"]
方法返回一个给定对象自身的所有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); // 2 console.log(objectSymbols); // [Symbol(a), Symbol(b)] console.log(objectSymbols[0]); // Symbol(a)
方法用于测试一个对象是否存在于另一个对象的原型链上。
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
方法返回指定对象的原型(内部[[Prototype]]
const prototype1 = {}; const object1 = Object.create(prototype1); console.log(Object.getPrototypeOf(object1) === prototype1); // expected output: true
proto
de l'objet nouvellement créé. La méthode 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
for...in
L'ordre est le même (la différence est que la boucle for-in
énumère également les propriétés dans la chaîne de prototypes). La méthode const object1 = { property1: 42, }; const object2 = Object.freeze(object1); object2.property1 = 33; // 严格模式会报错,非严格模式不报错,但是不执行 console.log(object2.property1); // 输出: 42
for...in</code. > L'ordre renvoyé lors du parcours de l'objet est cohérent. La méthode <p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">// 使用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</pre><div class="contentsignin">Copier après la connexion</div></div></p>Object.values()<h2></h2> renvoie un tableau de toutes les valeurs de propriété énumérables d'un objet donné lui-même. L'ordre des valeurs est le même que celui de l'utilisation du <code>for...in<. /code> boucle (la différence consiste en une boucle <code>for-in
énumérant les propriétés dans la chaîne de prototypes). La méthode 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
Symbol
comme noms) . La méthode 🎜rrreee🎜Object.getOwnPropertySymbols()🎜🎜 renvoie un tableau de toutes les propriétés Symbol
de l'objet donné lui-même. La méthode 🎜rrreee🎜Object.isPrototypeOf()🎜🎜 est utilisée pour tester si un objet existe sur la chaîne de prototypes d'un autre objet. La méthode 🎜rrreee🎜Object.propertyIsEnumerable()🎜🎜 renvoie une valeur booléenne indiquant si la propriété spécifiée est énumérable. La méthode 🎜rrreee🎜Object.getPrototypeOf()🎜🎜 renvoie l'attribut prototype (internal [[Prototype]]
) de l'objet spécifié. La méthode 🎜rrreee🎜Object.is()🎜🎜 détermine si. les deux valeurs sont la même valeur. La méthode 🎜rrreee🎜Object.preventExtensions()🎜🎜 rend un objet non extensible, c'est-à-dire que de nouvelles propriétés ne peuvent jamais être ajoutées. La méthode 🎜rrreee🎜Object.isExtensible()🎜🎜 détermine si un objet est extensible (si de nouvelles propriétés peuvent lui être ajoutées). La méthode 🎜rrreee🎜Object.freeze()🎜🎜 peut geler un objet. Le gel signifie que de nouveaux attributs ne peuvent pas être ajoutés à cet objet, les valeurs de ses attributs existants ne peuvent pas être modifiées, les attributs existants ne peuvent pas être supprimés et l'objet. ne peut pas être modifié. Il existe des propriétés énumérables, configurables et accessibles en écriture. Cette méthode renvoie l'objet gelé. La méthode 🎜rrreee🎜Object.isFrozen()🎜🎜 détermine si un objet est gelé. La méthode 🎜rrreee🎜Object.seal()🎜🎜 scelle un objet, empêchant l'ajout de nouvelles propriétés et marquant toutes les propriétés existantes comme non configurables. La valeur de la propriété actuelle peut être modifiée tant qu'elle est accessible en écriture. La méthode 🎜rrreee🎜Object.isSealed()🎜🎜 détermine si un objet est scellé. La méthode 🎜rrreee🎜Object.valueOf()🎜🎜 renvoie la valeur d'origine de l'objet spécifié. 🎜rrreee🎜Apprentissage recommandé : 🎜Tutoriel vidéo JavaScript🎜🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!