面向对象与原型 (Object Oriented & Prototype)
1. 原型链继承
javascript
function Animal(name) {
this.name = name;
}
Animal.prototype.speek = function () {
console.log(`${this.name} is speeking...`);
};
function Dog(name, age) {
// 继承属性
Animal.call(this, name);
this.age = age;
}
// 继承方法:使用 Object.create 避免调用父类构造函数
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.getAge = function () {
return this.age;
};
const dog = new Dog('wangcai', 3);
dog.speek();2. Class 类
ES6 语法糖写法。
javascript
class Person {
constructor(name, age) {
this.name = name || 'unknown';
this.age = age || 0;
}
sayHello() {
console.log(`Hi, I'm ${this.name}, age ${this.age}`);
}
}
class Student extends Person {
constructor(name, age, grade) {
super(name, age);
this.grade = grade || 1;
}
sayInfo() {
this.sayHello();
console.log(`Grade: ${this.grade}`);
}
}
const s = new Student('Lisa', 20, 2);
s.sayInfo();3. 手写 instanceof
instanceof 的核心原理是检查构造函数的 prototype 是否出现在对象的原型链上。
javascript
function myInstanceof(left, right) {
// 获取对象的原型
let proto = Object.getPrototypeOf(left);
// 构造函数的 prototype
const prototype = right.prototype;
while (proto) {
if (proto === prototype) return true;
// 继续向上查找
proto = Object.getPrototypeOf(proto);
}
return false;
}4. 手写深拷贝 (Deep Clone)
javascript
export function deepClone(obj, hash = new WeakMap()) {
if (obj === null || typeof obj !== 'object') return obj;
// 处理循环引用
if (hash.has(obj)) return hash.get(obj);
let clone = Array.isArray(obj) ? [] : {};
hash.set(obj, clone);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key], hash);
}
}
return clone;
}5. 查找对象深层属性
javascript
function findPropIn(propName, obj, visited = new Set()) {
if (obj == undefined || typeof obj !== 'object') return;
if (visited.has(obj)) return; // 避免循环引用死循环
visited.add(obj);
if (propName in obj) return obj[propName];
for (let key of Object.keys(obj)) {
let ret = findPropIn(propName, obj[key], visited);
if (ret !== undefined) return ret;
}
return undefined;
}