面向对象练习题(重写hasPubProperty)

148 阅读2分钟

1、

function Fn(obj, extend) {
    if (extend) {
        for (let key in obj) {
            this[key] = obj[key];
        }
        return;
    }
    this.a = 100;
    this.b = function () {};
}
Fn.prototype.c = function () {};
Fn.prototype = new Fn({
    x: 100,
    getX: function () {}
}, true);
let f = new Fn; 

2、for in 循环

(1)优先遍历数字属性,而且按照从小到大遍历;数字属性遍历完,再去遍历其他的

(2)无法遍历Symbol的私有属性

(3)遍历所属类原型上自定义的属性和方法「遍历了公有的:内置的是不可枚举的、自定义的属性是可枚举的」

for (let key in obj) {
    if (!obj.hasOwnProperty(key)) break; //解决问题三 ,不让其遍历公有属性
    console.log(key, obj[key]);
} 

3、获取私有的属性 (1)获取私有的属性:Object.keys(obj) OR Object.getOwnPropertyNames(obj) ;返回包含所有非symbol私有属性的数组;

(2)Object.getOwnPropertySymbols 获取所有的Symbol私有属性「数组」

(3)遍历一个对象所有的属性

[
    ...Object.keys(obj),
    ...Object.getOwnPropertySymbols(obj)
].forEach(key => {
    console.log(key, obj[key]);
}); 

4、练习题

 function C1(name) {
    if (name) {
        this.name = name;
    }
}
function C2(name) {
    this.name = name;
}
function C3(name) {
    this.name = name || 'join';
}
C1.prototype.name = 'Tom';
C2.prototype.name = 'Tom';
C3.prototype.name = 'Tom';
alert((new C1().name) + (new C2().name) + (new C3().name));

结果

第二个new C2().name 即使没有给name传值,那么也加上了私有属性name 为undefined

5、练习题

 function Fn() {
    let a = 1;
    this.a = a;
}
Fn.prototype.say = function () {
    this.a = 2;
}
Fn.prototype = new Fn;
let f1 = new Fn;

Fn.prototype.b = function () {
    this.a = 3;
};
console.log(f1.a);
console.log(f1.prototype);
console.log(f1.b);
console.log(f1.hasOwnProperty('b'));
console.log('b' in f1);
console.log(f1.constructor == Fn);

6、封装hasPubProperty

 let A = Symbol('AA');

function Fn() {
    this.x = 100;
    this[A] = 100;
    this.getX = function () { };
}
Fn.prototype[A] = 1000;
Fn.prototype.getX = function () { };
let f1 = new Fn;

// console.log(f1.hasOwnProperty('getX')); //->true  只要私有有这个属性,结果就是true
// console.log(f1.hasOwnProperty(A)); //->true  支持Symbol的私有属性检测

(1) 扩展到内置类的原型上,这样后期直接基于 对象.hasPubProperty(...) 即可调用 (2)Object.getPrototypeOf() 获取某个对象的原型

(3)代码

  Object.prototype.hasPubProperty = function hasPubProperty(attr) {
        // this->f1
        var self = this,
            prototype = Object.getPrototypeOf(self);
        while (prototype) {
            // 检测是否存在ATTR这个属性
            if (prototype.hasOwnProperty(attr)) return true;
            // 一直按照原型链查找
            prototype = Object.getPrototypeOf(prototype);
        }
        return false;
    };
    

(4)Object.keys(prototype)获取不到原型的内置属性,因为是不可枚举的 (5)测试

console.log(f1.hasPubProperty('x')); //->false
console.log(f1.hasPubProperty('getX')); //->true
console.log(f1.hasPubProperty(A)); //->true
console.log(f1.hasPubProperty('toString')); //->true   Object.prototype