JS中的可枚举属性与不可枚举属性
2018-03-28 20:50
288 查看
一、怎么判断属性是否可枚举
js中基本包装类型的原型属性是不可枚举的,如Object,
Array,
Number等,如果你写出这样的代码遍历其中的属性:
var num = new Number(); for(var pro in num) { console.log("num." + pro + " = " + num[pro]); }它的输出结果会是空。这是因为
Number中内置的属性是
不可枚举的,所以不能被
for…in访问到。
Object对象的
propertyIsEnumerable()方法可以判断此对象是否包含某个属性,并且这个属性是否可枚举。需要注意的是:如果判断的属性存在于
Object对象的原型内,不管它是否可枚举都会返回
false。
二、枚举性的作用
属性的枚举性会影响以下三个函数的结果:for…inObject.keys()JSON.stringify先看一个例子,按如下方法创建kxy对象:function Person() { this.name = "KXY"; } Person.prototype = { constructor: Person, job: "student", }; var kxy = new Person(); Object.defineProperty(kxy, "sex", { value: "female", enumerable: false });其中用defineProperty为对象定义了一个名为”sex”的不可枚举属性接下来做以下验证:
a.
for(var pro in kxy) { console.log("kxy." + pro + " = " + kxy[pro]); }结果:
kxy.name = KXY kxy.constructor = function Person() { this.name = "KXY"; } kxy.job = student可以看到除了”sex“之外的属性都遍历到了b.
console.log(Object.keys(kxy));返回结果:
["name"]
只包含”name”属性,说明该方法只能返回对象本身具有的可枚举属性。c.
console.log(JSON.stringify(kxy));返回结果:
{"name":"KXY"}
此方法也只能读取对象本身的可枚举属性,并序列化为JSON字符串(通过typeof JSON.stringify(kxy)得到string类型)。
Object.defineProperty()
上面用到了Object.defineProperty()方法,下面讲解下。
语法
Object.defineProperty(object, propertyname, descriptor)参数:object:必需。 要在其上添加或修改属性的对象。 这可能是一个本机 JavaScript 对象(即用户定义的对象或内置对象)或 DOM 对象。
propertyname:必需。 一个包含属性名称的字符串。
descriptor:必需。 属性描述符。 它可以针对数据属性或访问器属性。
返回值:已修改对象。备注:
可使用
Object.defineProperty函数来执行以下操作:向对象添加新属性。 当对象不具有指定的属性名称时,发生此操作。
修改现有属性的特性。 当对象已具有指定的属性名称时,发成此操作。
描述符对象中会提供属性定义,用于描述数据属性或访问器属性的特性。 描述符对象是
Object.defineProperty函数的参数。若要向对象添加多个属性或修改多个现有属性,可使用
Object.defineProperties函数 (JavaScript)。
异常
如果以下任一条件为 true,则引发 TypeError 异常:object 参数不是对象。此对象不可扩展且指定的属性名称不存在。
descriptor 具有 value 或 writable 特性,并且具有 get 或 set 特性。
descriptor 具有 get 或 set 特性,上述特性不是函数且已定义。
指定的属性名称已存在,现有属性具有 false 的 configurable 特性,且 descriptor 包含一个或多个与现有属性中特性不同的特性。 但是,当现有属性具有 false 的 configurable 特性和 true 的 writable 特性时,则允许 value 或 writable 特性不同。
添加数据属性
在以下示例中,Object.defineProperty函数向用户定义的对象添加数据属性。 若改为向现有的 DOM 对象添加属性,则取消对 var = window.document 行的注释。
var newLine = "<br />"; // Create a user-defined object. var obj = {}; // Add a data property to the object. Object.defineProperty(obj, "newDataProperty", { value: 101, writable: true, enumerable: true, configurable: true }); // Set the property value. obj.newDataProperty = 102; document.write("Property value: " + obj.newDataProperty + newLine); // Output: // Property value: 102若要列出对象属性,请将以下代码添加到此示例中。
var names = Object.getOwnPropertyNames(obj); for (var i = 0; i < names.length; i++) { var prop = names[i]; document.write(prop + ': ' + obj[prop]); document.write(newLine); } // Output: // newDataProperty: 102
修改数据属性
若要修改对象的属性特性,请将以下代码添加到前面所示的 addDataProperty 函数。 descriptor 参数只包含 writable 特性。 其他数据属性特性保持不变。// Modify the writable attribute of the property. Object.defineProperty(obj, "newDataProperty", { writable: false }); // List the property attributes by using a descriptor. // Get the descriptor with Object.getOwnPropertyDescriptor. var descriptor = Object.getOwnPropertyDescriptor(obj, "newDataProperty"); for (var prop in descriptor) { document.write(prop + ': ' + descriptor[prop]); document.write(newLine); } // Output // writable: false // value: 102 // configurable: true // enumerable: true
添加访问器属性
在以下示例中,Object.defineProperty 函数向用户定义的对象添加访问器属性。var newLine = "<br />"; // Create a user-defined object. var obj = {}; // Add an accessor property to the object. Object.defineProperty(obj, "newAccessorProperty", { set: function (x) { document.write("in property set accessor" + newLine); this.newaccpropvalue = x; }, get: function () { document.write("in property get accessor" + newLine); return this.newaccpropvalue; }, enumerable: true, configurable: true }); // Set the property value. obj.newAccessorProperty = 30; document.write("Property value: " + obj.newAccessorProperty + newLine); // Output: // in property set accessor // in property get accessor // Property value: 30若要列出对象属性,请将以下代码添加到此示例中。
var names = Object.getOwnPropertyNames(obj); for (var i = 0; i < names.length; i++) { var prop = names[i]; document.write(prop + ': ' + obj[prop]); document.write(newLine); } // Output: // in property get accessor // newAccessorProperty: 30
修改访问器属性
若要修改对象的访问器属性,请将以下代码添加前面所示的代码。 descriptor 参数只包含 get 访问器定义。 其他属性特性保持不变。// Modify the get accessor. Object.defineProperty(obj, "newAccessorProperty", { get: function () { return this.newaccpropvalue; } }); // List the property attributes by using a descriptor. // Get the descriptor with Object.getOwnPropertyDescriptor. var descriptor = Object.getOwnPropertyDescriptor(obj, "newAccessorProperty"); for (var prop in descriptor) { document.write(prop + ': ' + descriptor[prop]); document.write(newLine); } // Output: // get: function () { return this.newaccpropvalue; } // set: function (x) { document.write("in property set accessor" + newLine); this.newaccpropvalue = x; } // configurable: true // enumerable: true
修改 DOM 元素上的属性
下面的示例演示如何通过使用 Object.getOwnPropertyDescriptor 函数来获取和修改属性的属性描述符,从而自定义内置 DOM 属性。 对于此示例中,必须通过使用 ID 为“div”的 DIV 元素。// Get the querySelector property descriptor. var descriptor = Object.getOwnPropertyDescriptor(Element.prototype, "querySelector"); // Make the property read-only. descriptor.value = "query"; descriptor.writable = false; // Apply the changes to the Element prototype. Object.defineProperty(Element.prototype, "querySelector", descriptor); // Get a DOM element from the HTML body. var elem = document.getElementById("div"); // Attempt to change the value. This causes the revised value attribute to be called. elem.querySelector = "anotherQuery"; document.write(elem.querySelector); // Output: // query
Object.keys()
返回对象的可枚举属性和方法的名称。语法
Object.keys(object)参数object:必需。包含属性和方法的对象。这可以是您创建的对象或现有文档对象模型 (DOM) 对象。
返回值:一个数组,其中包含对象的可枚举属性和方法的名称。
异常:如果为 object 参数提供的值不是对象的名称,则将引发 TypeError 异常。
备注
keys方法仅返回可枚举属性和方法的名称。若要返回可枚举的和不可枚举的属性和方法的名称,可使用
Object.getOwnPropertyNames函数 (JavaScript)。
有关属性的 enumerable 特性的信息,请参见
Object.defineProperty函数 (JavaScript)和
Object.getOwnPropertyDescriptor函数 (JavaScript)。下面的示例创建一个对象,该对象具有三个属性和一个方法。然后使用 keys 方法获取该对象的属性和方法。js代码:
// Create a constructor function. function Pasta(grain, width, shape) { this.grain = grain; this.width = width; this.shape = shape; // Define a method. this.toString = function () { return (this.grain + ", " + this.width + ", " + this.shape); } } // Create an object. var spaghetti = new Pasta("wheat", 0.2, "circle"); // Put the enumerable properties and methods of the object in an array. var arr = Object.keys(spaghetti); document.write (arr); // Output: // grain,width,shape,toString下面的示例显示 Pasta 对象中以字母“g”开头的所有可枚举属性的名称。
// Create a constructor function. function Pasta(grain, width, shape) { this.grain = grain; this.width = width; this.shape = shape; } var polenta = new Pasta("corn", 1, "mush"); var keys = Object.keys(polenta).filter(CheckKey); document.write(keys); // Check whether the first character of a string is "g". function CheckKey(value) { var firstChar = value.substr(0, 1); if (firstChar.toLowerCase() == "g") return true; else return false; } // Output: // grain
Object.getOwnPropertyNames()
返回对象自己的属性的名称。一个对象的自己的属性是指直接对该对象定义的属性,而不是从该对象的原型继承的属性。对象的属性包括字段(对象)和函数。语法
Object.getOwnPropertyNames(object)参数:object,必需。包含自己的属性的对象。
返回值:一个数组,其中包含对象自己的属性的名称。
异常:如果为 object 参数提供的值不是对象的名称,则将引发 TypeError 异常。
备注
getOwnPropertyNames方法同时返回可枚举的和不可枚举的属性和方法的名称。若要仅返回可枚举的属性和方法的名称,可使用
Object.keys函数 (JavaScript)。下面的示例创建一个对象,该对象具有三个属性和一个方法。然后使用 getOwnPropertyNames 方法获取该对象自己的属性(包括方法)。
function Pasta(grain, width, shape) { // Define properties. this.grain = grain; this.width = width; this.shape = shape; this.toString = function () { return (this.grain + ", " + this.width + ", " + this.shape); } } // Create an object. var spaghetti = new Pasta("wheat", 0.2, "circle"); // Get the own property names. var arr = Object.getOwnPropertyNames(spaghetti); document.write (arr); // Output: // grain,width,shape,toString下面的示例显示了使用 Pasta 构造函数构造的 spaghetti 对象中以字母“S”开头的属性名。
function Pasta(grain, size, shape) { this.grain = grain; this.size = size; this.shape = shape; } var spaghetti = new Pasta("wheat", 2, "circle"); var names = Object.getOwnPropertyNames(spaghetti).filter(CheckKey); document.write(names); // Check whether the first character of a string is 's'. function CheckKey(value) { var firstChar = value.substr(0, 1); if (firstChar.toLowerCase() == 's') return true; else return false; } // Output: // size,shape
相关文章推荐
- JS基础篇--JS中的可枚举属性与不可枚举属性以及扩展
- 【js学习笔记-034】--枚举属性
- js中的枚举和不可枚举
- 可枚举属性和不可枚举属性
- JS 对象属性相关(检查属性、枚举属性等)
- JavaScript中的可枚举属性与不可枚举属性
- JavaScript中的可枚举属性与不可枚举属性
- 枚举属性和不可枚举属性
- 对象可枚举和不可枚举属性
- JS 对象属性相关--检查属性、枚举属性等
- js.枚举所有属性/函数
- JavaScript中的可枚举属性与不可枚举属性
- 浅谈 JS 对象添加 getter与 setter 的5种方法以及如何让对象属性不可配置或枚举
- JS 对象属性相关--检查属性、枚举属性等
- JS 对象属性"可枚举"
- JavaScript中的可枚举属性与不可枚举属性
- 枚举属性和不可枚举属性
- JS属性的枚举和删除
- 【新人笔记16.04.12】JS--枚举属性
- 可枚举属性与不可枚举属性