JavaScript之面向对象学习二(原型属性对象与in操作符)获取对象中所有属性的方法
1、原型属性对象于in操作符之in单独使用
有两种方式使用in操作符:单独使用和在for-in循环中使用。在单独使用中,代码如下:
function Person(){ } Person.prototype.name="张三"; Person.prototype.age=22; Person.prototype.job="coder"; Person.prototype.sayName=function(){ alert(this.name); } var person1=new Person(); var person2=new Person(); alert(person1.hasOwnProperty("name")); //输出:false,因为person1并没有自己的实例属性! alert("name" in person1); //输出:true,因为person1含有[[Prototype]]属性,该属性是一个指针,指向Person构造函数的原型属性对象。 // person1所指向的原型属性对象里面含有name属性,所以person1实例能够访问"name"属性。 person1.name="李四"; alert(person1.name); //输出"李四", 因为person1.name="李四";给person1实例定义了一个name属性,该属性将原型属性对象中的name属性屏蔽了 //屏蔽的原因是当执行person1.name代码时,JS会先到person1实例中寻找name属性,如果实例中没有该属性,则会去原型属性对象中寻找name属性 //所以这里在person1实例中找到了name属性,则JS就不会再去原型属性对象那个中寻找该属性,原型对象中的同名属性就会被忽略 alert(person1.hasOwnProperty("name"));//输出:true 因为person1.name="李四"给person1实例定义了一个实例属性 alert("name" in person1);//输出:true person1实例对象里面含有name属性,所以"name"属性可以访问 alert(person2.name); alert(person2.hasOwnProperty("name")); //输出:false person2实例没有自己的实例属性 alert("name" in person2); //输出:true person2所指向的原型属性对象里面含有name属性,所以person1实例能够访问"name"属性。 delete person1.name; alert(person1.hasOwnProperty("name")); //输出:false 因为delete person1.name;person1的实例被删除,所以此时person1没有实例属性 alert("name" in person1); ////输出:true person1所指向的原型属性对象里面含有name属性,所以person1实例能够访问"name"属性。
观察上面的代码我们发现,当in操作符单独使用的时候有一个规律如下:
属性 in 对象的实例
他的用法就是:判断这个属性能否被对象的实例所访问到,如果对象实例能访问到属性返回true,如果不能返回false;
注意:这里的属性可以是对象实例的属性,也可以是对象实例的[[Prototype]]属性指针,所指向的原型对象;
下面是结合Object.hasOwnProperty()和in判断一个属性到底是实例属性,还是实例对应原型对象的额属性,代码如下:
function Person(){ } Person.prototype.name="张三"; Person.prototype.age=22; Person.prototype.job="coder"; Person.prototype.sayName=function(){ alert(this.name); } var person1=new Person(); var person2=new Person(); /* @param object ---对象的实例名 @param name ---需要判断的对象属性 功能:判断name是实例的原型属性对象的属性还是实例的实例属性 */ function hasPrototypePrototype(object,name){ return !object.hasOwnProperty(name) && (name in object); } alert(hasPrototypePrototype(person1,"name")); //输出:true 说明person1能访问"name"属性,person1的实例属性中没有"name"属性,说明"name"属性是原型对象中属性 person1.name="李四"; alert(hasPrototypePrototype(person1,"name")); //输出:false 有两种情况 1、"name"属性既不是实例属性,也不是原型对象属性 2、person1能访问"name"属性,person1有"name"属性
2、原型属性对象与与in操作符之for-in结合使用
在使用for-in循环时,返回的是所有能够通过对象访问的、可枚举的属性,既包括实例中的属性又包括原型对象中的属性;
注意:屏蔽了原型中不可枚举属性(即将[[Enumerable]]设置为false的属性)也会在for-in循环中返回,因为根据规定,所有开发人员定义的属性都是可枚举的---只有IE8即更早版本中例外
代码如下:
var o={ toString:function(){ return "My Object"; } } for(var property in o){ if(property=="toString"){ alert("Found toString"); //在IE8 中不显示 } }
输出:Found toString,
注意:在IE中存在一个bug,因为其实现认为原型的toString()方法被打上了值为false的[[Enumerable]]标记(所以该属性无法被循环),因此应该跳过该属性,所以我们就看不到警告框,所以该bug会影响默认不可枚举的所有属性和方法,包括:hasOwnProperty()、propertyIsEnumerable()、toLocaleString、toString、valueOf()。
ECMAScript 5也将constructor和prototype属性的[[Enumerable]]特性设置为false,但并不是所有的浏览器都照此实现。
3、使用Object.keys()方法获取指定对象中所有可枚举的实例属性
ECMAScript 5中提供了Object.keys()方法。这个方法接收一个对象作为参数,返回一个包含所有可枚举属性的字符串数组,代码如下:
function Person(){ } Person.prototype.name="张三"; Person.prototype.age=22; Person.prototype.job="coder"; Person.prototype.sayName=function(){ alert(this.name); } var keys=Object.keys(Person.prototype); //Person.prototype =》获取Person构造函数的原型属性对象 ; //Object.keys(Person.prototype)=》获取原型属性对象的所有属性名,是键不是值 alert(keys); //输出name、age、job、sayName var person=new Person(); person.name="李四"; person.age=22; var personkeys=Object.keys(person); //获取person实例的属性不包含其原型对象的属性。 alert(personkeys); //输出:name、age var allkeys=Object.getOwnPropertyNames(Person.prototype); //获取Person构造函数原型对象的所有属性(包括不可枚举的属性([[Enumerable]]设为false的属性)) alert(allkeys);//输出:constructor,name,age,job,sayName 注意:在ECMAScript 5中constructor属性是不可枚举的
相关文章
- JavaScript图形实例:玩转正方形
- Javascript中prototype属性详解
- JavaScript 事件不触发
- 第七节:语法总结(1)(自动属性、out参数、对象初始化器、var和dynamic等) 图片放大镜 JavaScript-基础 用javascript写原生ajax(笔记) 初遇 Asp.net MVC 数据库依赖缓存那些事儿 前端JS 与 后台C# 之间JSON序列化与反序列化(笔记)
- Javascript将字符串日期格式化为yyyy-mm-dd的方法 js number 类型 没有length 属性 string类型才有
- Html中利用JavaScript根据屏幕分辨率打开相应的页面!(示例)
- JavaScript - 批量替换对象数组中的属性名(快速将二维数组对象中的键名进行大量替换)传入原来的属性名和要修改的属性名即可,适用于 js vue nuxt uniapp等项目,详细示例代码教程
- JavaScript - 二维对象数组去重(根据某一属性)
- 【JavaScript】理解与使用Javascript中的回调函数
- Javascript基础知识
- ajax-异步JavaScript和XML
- 【JavaScript】Json属性提取
- 《JavaScript入门经典(第6版)》——1.3 JavaScript简介
- 《JavaScript面向对象精要》——1.5 访问属性
- 《JavaScript面向对象精要》——1.5 访问属性
- 《JavaScript启示录》——1.17 动态属性支持易变对象
- 《JavaScript启示录》——1.18 构造函数实例都拥有指向其构造函数的Constructor属性
- 《JavaScript高效图形编程(修订版)》——2.4 IE6背景图像缓存
- 加深对 JavaScript This 的理解
- Javascript: hash tables in javascript
- 20个常用的JavaScript字符串方法
- JavaScript中Map和ForEach的区别
- 【JavaScript从入门到精通】第二课 初探JavaScript魅力-02
- JavaScript之面向对象的概念,对象属性和对象属性的特性简介
- JavaScript之ClassName属性学习
- JavaScript之childNodes属性、nodeType属性学习
- javascript的创建对象object.create()和属性检测hasOwnPrototype()和propertyIsEnumerable()
- JavaScript 自制可以替换属性的模板引擎(Template)