从零开始学_JavaScript_系列(35)——继承与遍历的对照表
2017-05-31 11:36
381 查看
继承
属性的继承有多种方式,但简单来说,分为继承后在本身属性上,以及在继承的属性在原型链上。前者的典型情况是通过call、apply或者Object.assign()等,他们之间还略有区别(但不影响遍历)。
后者的典型情况是通过prototype来继承,属性不在对象本身上,而是在例如
obj.__proto__上,或者更深一层等。
遍历
遍历的方法也有很多种,兼容旧版本的常见方法是for…in,之后还有Object.keys()等。当我们需要遍历对象时,属性位于哪里,以及是否可枚举,将影响遍历的结果。故这里列出一个表格作为对照参考。
方法 | 原型链继承(原型链上的属性) | call继承(在实例上的属性) | 普通属性,但enumerable为false |
for…in | 显示 | 显示 | 不显示 |
Object.keys() | 不显示 | 显示 | 不显示 |
JSON.stringify() | 不显示 | 显示 | 不显示 |
Object.getOwnPropertyNames() | 不显示 | 显示 | 显示 |
Reflect.ownKeys() | 不显示 | 显示 | 显示 |
Object.getOwnPropertySymbols() | 不显示 | 不显示 | 不显示 |
遍历要求 | 方法 |
普通的情况 | Object.keys() |
本身 + 原型链 | for…in |
本身,且包括枚举属性被设置为false的key | Object.getOwnPropertyNames() Reflect.ownKeys() |
兼容低版本IE | for…in(但注意原型链上的是否需要) |
只获取不能枚举的属性 | Object.getOwnPropertyNames()获取全部 再排除Object.keys() |
只获取原型链上(不包括自己的) | for..in先获取 再排除掉普通的 |
原型链上包括不可枚举的 | 手动递归__proto__属性 然后每一层Object.getOwnPropertyNames()获取 |
原型链上,只要不可枚举的 | 手动递归__proto__属性 然后每一层先获取全部再排除普通 |
``` //继承方式 //原型链继承 function Child() { this.a = "a"; } function Father() { this.b = "b"; } Child.prototype = new Father(); let foo = new Child(); //call继承 function AnotherFather() { this.b = "b"; } function AnotherChild() { this.a = "A"; AnotherFather.call(this); } let bar = new AnotherChild(); //其他,普通继承但enumberable值为false let obj = Object.defineProperty({}, "a", { value: "a", enumerable: false }) //遍历方式 //for...in console.log("for...in"); let arrFoo = []; for (let i in foo) { arrFoo.push(i); } let arrBar = []; for (let i in bar) { arrBar.push(i); } let objArr = []; for (let i in obj) { objArr.push(i); } console.log(arrFoo); //["a", "b"] console.log(arrBar); //["a", "b"] console.log(objArr); //[] console.log("-----"); //Object.keys(); console.log("Object.keys()"); console.log(Object.keys(foo)); //["a"] console.log(Object.keys(bar)); //["a", "b"] console.log(Object.keys(obj)); //[] console.log("-----"); //JSON.stringify() console.log("JSON.stringify()"); console.log(JSON.stringify(foo)); //{"a":"a"} console.log(JSON.stringify(bar)); //{"a":"A","b":"b"} console.log(JSON.stringify(obj)); //{} console.log("-----") //Object.getOwnPropertyNames()返回一个数组,包含对象自身的所有属性(不含Symbol属性,但是包括不可枚举属性)。 console.log("Object.getOwnPropertyNames()"); console.log(Object.getOwnPropertyNames(foo)); //["a"] console.log(Object.getOwnPropertyNames(bar)); //["a", "b"] console.log(Object.getOwnPropertyNames(obj)); //["a"] console.log("-----"); //Reflect.ownKeys()返回一个数组,包含对象自身的所有属性,不管属性名是Symbol或字符串,也不管是否可枚举。 console.log("Reflect.ownKeys()"); console.log(Reflect.ownKeys(foo)); //["a"] console.log(Reflect.ownKeys(bar)); //["a", "b"] console.log(Reflect.ownKeys(obj)); //["a"] console.log("-----"); //Object.getOwnPropertySymbols()返回一个数组,包含对象自身的所有Symbol属性 console.log("Object.getOwnPropertySymbols()"); console.log(Object.getOwnPropertySymbols(foo)); //[] console.log(Object.getOwnPropertySymbols(bar)); //[] console.log(Object.getOwnPropertySymbols(obj)); //[] //for...of只能用于迭代有迭代器接口的对象,普通对象是没有这个接口的,所以不行
“`
相关文章推荐
- 从零开始学_JavaScript_系列(65)——class的继承(2)super、extends与多重继承
- 从零开始学_JavaScript_系列(56)——Generator函数(4)简写,this与继承
- 从零开始学_JavaScript_系列(18)——dojo(7)(dojo中类的继承)
- 从零开始学_JavaScript_系列(42)——简述js的八种继承方式
- 从零开始学_JavaScript_系列(64)——class的继承(1)基本概念、继承构造函数和class
- [原]JavaScript必备知识系列-继承的实现方式
- 从零开始学_JavaScript_系列(33)——dojo 的 tree
- 从零开始学_JavaScript_系列(17)——dojo(6)(声明一个类declare)
- 从零开始学_JavaScript_系列(52)——Iterator接口与for...of
- 从零开始学_JavaScript_系列(44)——ES6新增数据结构:Set类型和WeakSet
- 征服JavaScript面试系列:类继承和原型继承的区别
- 从零开始学_JavaScript_系列(30)——NodeList
- 从零开始构建JavaScript框架4——DOM遍历2
- 深入理解JavaScript系列(35):设计模式之迭代器模式
- javascript继承学习系列之五:其他方式
- 从零开始学_JavaScript_系列(27)——dojo的文档相关模块
- 从零开始学_JavaScript_系列(12)——jquery<2>(高度自适应,哈希地址及检测,单页面技术)
- 从零开始学_JavaScript_系列(43)——Symbol简述
- 从零开始学_JavaScript_系列(34)——将canvas获取的图片下载到本地
- 从零开始学_JavaScript_系列(26)——dojo的aspect方法