JS 检测公有属性方法封装(使用ES5方法)

检测属性方法

in

  • 检测当前对象是否存在某个属性,不论是公有还是私有,只要有,返回 true

    [attr] in [object]

function Fn() {
    this.age = 14;
    this.name = "lion";
}
Fn.prototype.category = "animal";
let f = new Fn();
console.log("name" in f);     // true
console.log("category" in f); // true

hasOwnProperty

  • 检测一个属性是不是这个对象的私有属性,如果是,返回true

    [object].hasOwnProperty([attr])

function Fn() {
    this.age = 14;
    this.name = "lion";
}
Fn.prototype.category = "animal";
let f = new Fn();
console.log(f.hasOwnProperty("name"));     // true
console.log(f.hasOwnProperty("category")); // false

尝试封装检测公有属性

  • 了解了 inhasOwnProperty 之后我们可以尝试封装检测公有属性的方法

写出来大概是如下这样:

Object.prototype.hasPubProperty = function (attr) {
    return attr in obj && !obj.hasOwnProperty(attr);
}
  • 但是这个是有弊端的,比如:某个属性既是私有的,也是公有的,就检测不出来了
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();
// name既是公有的也是私有的
console.log(f.hasPubProperty("name"));     // false
console.log(f.hasPubProperty("category")); // true

这样肯定不行,有没有什么方法可以避免这个问题,接下来需要看一下 Object 的其它几个方法

检测公有属性

  • 期望结果如下:
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();

// age是私有方法
console.log(f.hasPubProperty("age"));      // false
// name既是公有的也是私有的
console.log(f.hasPubProperty("name"));     // true
// A(Symbol)既是公有的也是私有的
console.log(f.hasPubProperty(A));          // true

Object.getPrototypeOf

如果了解前置知识,可直接跳到封装方法处

前置知识

ES5新增方法

  • Object.getPrototypeOf([object]) 方法返回指定对象自身的原型
Fn.prototype === Object.getPrototypeOf(f); // true
封装方法
  • 借用原型链查找公有属性
Object.prototype.hasPubProperty = function (attr) {
    let self = this,
        prototype = Object.getPrototypeOf(self);
    while (prototype) {
        // 检测是否存在attr这个属性
        if (prototype.hasOwnProperty(attr)) return true;
        // 一直按照原型链查找
        prototype = Object.getPrototypeOf(prototype);
    }
    return false
}
  • 因为用到了 hasOwnProperty,它不仅能检测可枚举属性还可以检测内置属性
console.log(f.hasPubProperty("toString")); // true
console.log(f.hasPubProperty("valueOf"));  // true

Object.keys

如果了解前置知识,可直接跳到封装方法处

前置知识

ES5新增方法

  • Object.keys([object]) 方法会返回一个数组,数组里面存放指定对象自身的可枚举属性
  • Object.keys([object]) 方法返回非 Symbol 私有属性的数组
Object.prototype.xx = "xx";
let obj = {
    name: "lion",
    age: 12,
    3: 200,
    0: 100,
    [Symbol("a")]: function () {}
}
console.log(Object.keys(obj)); // [ '0', '3', 'name', 'age' ]
  • 如果想获取 Symbol 私有属性,可以使用 Object.getOwnPropertySymbols(obj)
console.log(Object.getOwnPropertySymbols(obj)); // [ Symbol(a) ]
  • 如果想获取所有私有属性(包括Symbol)到一个数组中,可以这么写
[...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)];
// ['0', '3', 'name', 'age', Symbol(a)]
封装方法
Object.prototype.hasPubProperty = function (attr) {
    var self = this,
        prototype = Object.getPrototypeOf(self);
    while (prototype) {
        // 检测是否存在attr这个属性
        var keys = Object.keys(prototype);
        // 检测浏览器是否支持Symbol
        if (typeof Symbol !== "undefined") {
            // 如果支持,把Symbol属性合并到数组中
            keys = keys.concat(Object.getOwnPropertySymbols(prototype));
        }
        // 一直按照原型链查找
        prototype = Object.getPrototypeOf(prototype);
    }
    return false
}
  • 注意:内置属性不可以枚举,Object.keys([object]) 方法检测不到内置属性
console.log(f.hasPubProperty("toString")); // false
console.log(f.hasPubProperty("valueOf"));  // false
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值