检测属性方法
in
1 2 3 4 5 6 7 8
| function Fn() { this.age = 14; this.name = "lion"; } Fn.prototype.category = "animal"; let f = new Fn(); console.log("name" in f); console.log("category" in f);
|
hasOwnProperty
1 2 3 4 5 6 7 8
| function Fn() { this.age = 14; this.name = "lion"; } Fn.prototype.category = "animal"; let f = new Fn(); console.log(f.hasOwnProperty("name")); console.log(f.hasOwnProperty("category"));
|
尝试封装检测公有属性
- 了解了
in
和 hasOwnProperty
之后我们可以尝试封装检测公有属性的方法
写出来大概是如下这样:
1 2 3
| Object.prototype.hasPubProperty = function (attr) { return attr in obj && !obj.hasOwnProperty(attr); }
|
- 但是这个是有弊端的,比如:某个属性既是私有的,也是公有的,就检测不出来了
1 2 3 4 5 6 7 8 9 10 11 12 13
| Object.prototype.hasPubProperty = function (attr) { return attr in this && !this.hasOwnProperty(attr); } function Fn() { this.age = 14; this.name = "lion"; } Fn.prototype.category = "animal"; Fn.prototype.name = "bird"; let f = new Fn();
console.log(f.hasPubProperty("name")); console.log(f.hasPubProperty("category"));
|
这样肯定不行,有没有什么方法可以避免这个问题,接下来需要看一下 Object 的其它几个方法
检测公有属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| function Fn() { this.age = 14; this[A] = 100; this.name = "lion"; } let A = Symbol("a"); Fn.prototype.name = "bird"; Fn.prototype[A] = 200; let f = new Fn();
console.log(f.hasPubProperty("age"));
console.log(f.hasPubProperty("name"));
console.log(f.hasPubProperty(A));
|
Object.getPrototypeOf
如果了解前置知识,可直接跳到封装方法处
前置知识
ES5新增方法
Object.getPrototypeOf([object])
方法返回指定对象自身的原型
1
| Fn.prototype === Object.getPrototypeOf(f);
|
封装方法
1 2 3 4 5 6 7 8 9 10 11
| Object.prototype.hasPubProperty = function (attr) { let self = this, prototype = Object.getPrototypeOf(self); while (prototype) { if (prototype.hasOwnProperty(attr)) return true; prototype = Object.getPrototypeOf(prototype); } return false }
|
- 因为用到了
hasOwnProperty
,它不仅能检测可枚举属性还可以检测内置属性
1 2
| console.log(f.hasPubProperty("toString")); console.log(f.hasPubProperty("valueOf"));
|
Object.keys
如果了解前置知识,可直接跳到封装方法处
前置知识
ES5新增方法
Object.keys([object])
方法会返回一个数组,数组里面存放指定对象自身的可枚举属性
Object.keys([object])
方法返回非 Symbol 私有属性的数组
1 2 3 4 5 6 7 8 9
| Object.prototype.xx = "xx"; let obj = { name: "lion", age: 12, 3: 200, 0: 100, [Symbol("a")]: function () {} } console.log(Object.keys(obj));
|
- 如果想获取 Symbol 私有属性,可以使用
Object.getOwnPropertySymbols(obj)
1
| console.log(Object.getOwnPropertySymbols(obj));
|
- 如果想获取所有私有属性(包括Symbol)到一个数组中,可以这么写
1 2
| [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)];
|
封装方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Object.prototype.hasPubProperty = function (attr) { var self = this, prototype = Object.getPrototypeOf(self); while (prototype) { var keys = Object.keys(prototype); if (typeof Symbol !== "undefined") { keys = keys.concat(Object.getOwnPropertySymbols(prototype)); } prototype = Object.getPrototypeOf(prototype); } return false }
|
- 注意:内置属性不可以枚举,
Object.keys([object])
方法检测不到内置属性
1 2
| console.log(f.hasPubProperty("toString")); console.log(f.hasPubProperty("valueOf"));
|