首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Javascript原型继承和"instanceof“

基础概念

JavaScript原型继承是JavaScript中实现对象继承的一种机制。每个JavaScript对象都有一个内部属性[[Prototype]](在ES6及以后版本中可以通过__proto__属性访问),指向它的原型对象。当试图访问一个对象的属性时,如果该对象本身没有这个属性,JavaScript会沿着原型链向上查找,直到找到该属性或到达原型链的顶端(null)。

"instanceof"是JavaScript中的一个操作符,用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上。换句话说,它用来判断一个对象是否是某个构造函数的实例。

优势

  • 原型继承的优势在于它允许对象共享属性和方法,而不需要复制这些属性和方法到每个实例中,从而节省内存。
  • "instanceof"的优势在于它提供了一种简单的方式来检查对象的类型,这在类型检查和多态性实现中非常有用。

类型

  • 原型继承主要有两种类型:构造函数继承和原型链继承。
    • 构造函数继承:通过call()apply()方法将父类构造函数的上下文绑定到子类实例上,从而实现属性继承。
    • 原型链继承:通过将子类的prototype设置为父类的实例来实现继承。

应用场景

  • 原型继承常用于创建具有共同方法和属性的对象集合,例如创建一组具有相似行为的DOM元素。
  • "instanceof"常用于确定对象的类型,以便在不同的逻辑分支中执行不同的操作,或者在框架和库中进行类型检查。

遇到的问题及解决方法

问题:为什么使用instanceof时会出现误判?

原因instanceof操作符在判断时是基于原型链的,如果原型链被修改或者存在多个全局环境(如多个iframe),可能会导致误判。

解决方法

代码语言:txt
复制
function safeInstanceOf(obj, constructor) {
  if (typeof constructor !== 'function') {
    throw new TypeError('Right-hand side of instanceof is not callable');
  }
  let prototype = constructor.prototype;
  let currentProto = Object.getPrototypeOf(obj);
  while (currentProto) {
    if (currentProto === prototype) {
      return true;
    }
    currentProto = Object.getPrototypeOf(currentProto);
  }
  return false;
}

问题:原型继承中的属性覆盖问题

原因:在原型链上,如果子类和父类有同名的属性或方法,子类的属性会覆盖父类的属性。

解决方法

代码语言:txt
复制
function Parent() {
  this.name = 'Parent';
}

Parent.prototype.sayHello = function() {
  console.log('Hello from Parent');
};

function Child() {
  this.name = 'Child';
}

Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

Child.prototype.sayHello = function() {
  console.log('Hello from Child');
};

const child = new Child();
console.log(child.name); // Child
child.sayHello(); // Hello from Child

参考链接

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • 领券