面试题答案
一键面试原型链查找机制
在JavaScript中,当访问对象的属性或方法时,首先会在对象自身上查找,如果找不到,则会沿着原型链向上查找,直到找到该属性或方法,或者到达原型链顶端(Object.prototype
)。对于操作符重载模拟,同样遵循这个规则。
this指向问题
this
在JavaScript中根据函数的调用方式来确定其指向。在对象方法中调用时,this
通常指向调用该方法的对象。在操作符重载模拟时,需要确保this
指向正确的对象,特别是在继承体系中,以保证操作的正确性。
可能出现的陷阱
- 原型链污染:错误地修改原型链可能会影响到整个继承体系,导致意外的行为。
this
指向错误:如果在继承体系中没有正确处理this
,可能会导致操作针对错误的对象进行。- 方法覆盖问题:子类可能会意外覆盖父类的操作符重载方法,导致不一致的行为。
代码示例
// 定义父类
function Parent() {
this.value = 0;
}
// 为父类定义模拟加法操作符重载的方法
Parent.prototype.add = function(other) {
return this.value + other.value;
};
// 定义子类,继承自Parent
function Child() {
Parent.call(this); // 调用父类构造函数,确保正确的this指向
this.value = 1;
}
// 设置Child的原型为Parent的实例,建立继承关系
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
// 子类可以重写add方法,同时保持一致性
Child.prototype.add = function(other) {
return this.value + other.value + 1; // 子类的加法操作可以有自己的逻辑,但保持与父类类似的行为
};
// 创建父类实例
const parentInstance = new Parent();
// 创建子类实例
const childInstance = new Child();
// 测试操作符重载模拟
console.log(parentInstance.add(childInstance)); // 输出:1
console.log(childInstance.add(parentInstance)); // 输出:2
代码注释说明
- 父类定义:
function Parent()
:定义父类Parent
,构造函数中初始化this.value
为0。Parent.prototype.add
:为Parent
类的原型添加add
方法,模拟加法操作符重载,返回两个实例的value
之和。
- 子类定义:
function Child()
:定义子类Child
,在构造函数中调用Parent.call(this)
,确保this
指向正确,并初始化this.value
为1。Child.prototype = Object.create(Parent.prototype)
:设置Child
的原型为Parent
的实例,建立继承关系。Child.prototype.constructor = Child
:修复子类原型的构造函数指向。Child.prototype.add
:子类重写add
方法,在父类逻辑基础上增加1,保持操作符行为的一致性。
- 实例化与测试:
const parentInstance = new Parent()
:创建父类实例。const childInstance = new Child()
:创建子类实例。console.log(parentInstance.add(childInstance))
:测试父类实例调用add
方法,输出1。console.log(childInstance.add(parentInstance))
:测试子类实例调用add
方法,输出2。