首页
学习
活动
专区
工具
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

参考链接

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

相关·内容

JavaScript继承和原型链

继承和原型链大家好,这篇文章我将会和大家分享JS关于继承和原型链的有关知识。首先,让我们了解一下什么是原型对象。...请看下面的例子遵循ECMAScript标准,[[Prototype]]用于表示实例对象的原型属性,这和非JavaScript标准但很多浏览器实现的proto属性一样,但不应与prototype混淆。...[[Prototype]]指向Object.prototypenull位于原型链的顶端,根据定义,null就是没有原型。继承属性JavaScript对象是动态的属性“包”,它有一个指向它的原型的链。...函数的继承和其他属性的继承没有差别,包括上面的属性屏蔽。需要注意的是,当继承的函数被调用时,this指向的是当前继承的对象,而不是继承的函数所在的原型对象。...但它们是不同的,JavaScript仍然基于原型。

45040

instanceof运算符的实质:Java继承链与JavaScript原型链

JavaScript instanceof The instanceof operator tests whether the prototype property of a constructor...instanceof操作符的内部实现机制和隐式原型、显式原型有直接的关系。instanceof的左值一般是一个对象,右值一般是一个构造函数,用来判断左值是否是右值的实例。...__proto__;   } } 在《再谈javascriptjs原型与原型链及继承相关问题》 根据上图展示的Object和Function的继承依赖关系,我们可以通过instanceof操作符来看一下...: Right-hand side of 'instanceof' is not an object 其实对比起来,和java 大同小异 转载本站文章《instanceof运算符的实质:Java继承链与...JavaScript原型链》, 请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/js/2015_1231_8493.html

48331
  • instanceof运算符的实质:Java继承链与JavaScript原型链

    JavaScript instanceof The instanceof operator tests whether the prototype property of a constructor...instanceof操作符的内部实现机制和隐式原型、显式原型有直接的关系。instanceof的左值一般是一个对象,右值一般是一个构造函数,用来判断左值是否是右值的实例。...__proto__;   } } 在《再谈javascriptjs原型与原型链及继承相关问题》 根据上图展示的Object和Function的继承依赖关系,我们可以通过instanceof操作符来看一下...: Right-hand side of 'instanceof' is not an object 其实对比起来,和java 大同小异 转载本站文章《instanceof运算符的实质:Java继承链与...JavaScript原型链》, 请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/js/2015_1231_8493.html

    50410

    JavaScript原型与继承

    (在 ES2015/ES6 中引入了 class 关键字,但那只是语法糖,JavaScript 仍然是基于原型的)。 当谈到继承时,JavaScript 只有一种结构:对象。...几乎所有 JavaScript 中的对象都是位于原型链顶端的 Object 的实例。 尽管这种原型继承通常被认为是 JavaScript 的弱点之一,但是原型继承模型本身实际上比经典模型更强大。...例如,在原型模型的基础上构建经典模型相当简单。 ---- 基于原型链的继承 继承属性 JavaScript 对象是动态的属性“包”(指其自己的属性)。...当继承的函数被调用时,this 指向的是当前继承的对象,而不是继承的函数所在的原型对象。...为了最佳的学习体验,我们强烈建议阁下打开浏览器的控制台(在Chrome和火狐浏览器中,按Ctrl+Shift+I即可),进入“console”选项卡,然后把如下的JavaScript代码复制粘贴到窗口中

    53110

    JavaScript原型链继承

    什么是原型链继承?在JavaScript中,每个对象都有一个原型(prototype),原型本身也是一个对象。...当我们访问一个对象的属性或方法时,如果该对象本身没有该属性或方法,JavaScript会自动去它的原型对象中查找。...如果原型对象也没有找到,JavaScript会继续在原型对象的原型上查找,这样形成了一个原型链。原型链继承是基于原型链的继承机制。通过将一个对象的原型指向另一个对象,从而实现对属性和方法的继承。...原型链继承的特点原型链继承具有以下特点:属性和方法的继承:通过原型链继承,子对象可以继承父对象的属性和方法。...原型链继承的注意事项在使用原型链继承时,需要注意以下几点:避免直接修改原型对象:直接修改原型对象可能会影响所有继承了该原型链的对象。推荐使用原型对象的方法来添加属性和方法。

    39810

    JavaScript难点:原型、原型链、继承、new、prototype和constructor

    原型 原型(prototype)是 JavaScript 中对象的一个特殊属性,它用于实现属性和方法的继承。...原型链 任何一个实例,通过原型链,都能找到它上面的原型,该原型对象中的方法和属性,可以被所有的原型实例共享,原型对象中依然有它自身的原型,当我们访问一个实例属性或方法时,如果自身没有,就会一级一级地去原型对象上找...继承 JavaScript 不像 Java、C++ 这种纯面向对象的语言,可以通过类实现继承,JavaScript中的继承是通过原型实现的,即使 ES6 中新增的 class 类也只是原型的语法糖而已。...为什么通过 prototype 修改原型实现继承后要重置 custructor?...我们可以通过将一个构造函数的 prototype 指向另一个构造函数来实现继承父类的属性和方法,但是往往还会额外加一个 Child.prototype.constructor = Child,这是因为直接通过

    13310

    原型、原型链和原型继承

    原型继承 编程中对象继承,有类继承和原型继承: 类继承形式上就是,extends 关键字,继承之后,子类就会拥有父类的属性和方法,如下: // 以下是 ES6 class 语法,语法上同类继承一样,但实际上仍然是原型继承...上一小节是从继承的层面,介绍原型继承,但是没有具体说什么是原型。...我们先说清楚原型,再回来解释上面的 prototype 的作用是什么。 在javascript里面,对象都有一个隐藏对象 “[[Prototype]]”, 获取该对象可以通过 target....而javascript 运行环境中是预设了一些对象来作为原型的,如图: 查找属性或方法时,向上追溯,经过的原型,就形成了一条链,所谓原型链。 至于运行环境预设了哪些原型,已经他们的关系如何,为什么?...等等,大家可以看看这篇文章:JavaScript 世界万物诞生记, 真的精彩!

    76110

    JavaScript原型链与继承

    JavaScript中函数是一等公民,函数是对象。函数也是对象,只不过自己能()执行。...Cat); //true console.log(hellokitty instanceof Dog); //true instanceof 运算符的机理: 遍访hellokitty这个对象的原型链上的每个原型对象...总结一下,A instanceof B, 不能证明A是new B()出来的,因为可能是继承。 5....",1001,19); for(var key in xiaohong){ console.log(key); } console.log(xiaohong); 方法都在构造函数中定义, 只能继承父类的实例属性和方法...组合继承 就是将原型链继承和构造函数继承组合在一起;继承两个优点 通过调用父类构造,继承父类的属性并保留传参的优点, 然后再通过将父类实例作为子类原型,实现函数复用 function People(name

    1.6K50

    前端面试题每日一练,测测你对JavaScript原型继承和 instanceof 的理解

    今天的挑战题目涉及到JavaScript中的原型继承和 instanceof 操作符的使用。我们将通过分析一个关于构造函数和原型链的例子,来探索对象继承的机制,以及如何判断对象的类型。...这行代码的作用是让 Circle 的原型 (Circle.prototype) 继承自 Shape 的原型 (Shape.prototype)。...但是,shape 对象的原型链并不直接包含 Circle.prototype,而是直接指向 Shape.prototype,因此: shape instanceof Circle 会返回 false,因为...输出结果 根据上述分析,最终的输出结果是: console.log(shape instanceof Circle); // 输出 false 结束 这道题目展示了JavaScript中的原型继承和...欢迎在评论区分享你的答案和见解! 每天一道面试题,帮助你提高编程技能,不断进步!记得关注哦!

    9210

    如果使用 JavaScript 原型实现继承

    作者:Indermohan Sing 译者:前端小智 来源:blog 在这篇文章中,我们将讨论原型以及如何在 JS 中使用它们进行继承。我们还将会看到原型方法与基于类的继承有何不同。...但是这种方法需要更多的时间和精力,并且会引入更多的bug。 重用SmartPhone类中的功能,这就是继承的作用,继承也是重用其他类/对象中功能的一种方式。...例如,类C继承自类B,而类B继承自类A 值得注意的是,类本身并没有做任何事情。在从类创建对象之前,实际上没有完成任何工作。我们将看到它为什么不同于JavaScript。...使用原型继承的各种方法 在 JS 中,无论我们如何创建对象,只有原型继承,但这些方式还有一些区别,来看看: 对象字面量 在JavaScript中创建对象的最简单方法是使用对象字面量: let obj =...但是阅读和理解起来要干净得多。 ---- 原文:https://javascript.info/proto...

    69320

    JavaScript进阶-原型链与继承

    在JavaScript中,原型链和继承是理解对象间关系和实现代码复用的核心概念。这两个机制共同构成了JavaScript面向对象编程的基础。...合理组织原型结构:保持原型链的简洁,避免不必要的层级。 使用Object.create或类(class)语法糖:更清晰地管理原型和继承关系。...继承:代码复用的艺术 继承方式 JavaScript提供了多种实现继承的方式,包括但不限于: 原型链继承:通过将子类型的原型设置为父类型的实例。...构造函数继承:通过在子类构造函数内部调用父类构造函数。 组合继承(常用):结合原型链继承和构造函数继承。 ES6 Class继承:基于class关键字的语法糖,简化了继承过程。...中的原型链和继承机制,对于深入掌握这门语言至关重要。

    18610

    JavaScript原型链继承与盗用构造函数继承

    ---- theme: channing-cyan 这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战 昨天我们讲解了原型和原型链,今天我们说一下继承,顺便再重温一下原型链 什么是继承 继承这个词比较容易理解...这个就是继承。我们直接上干货。 原型链继承 原型链继承是js中的主要继承方式,它的基本思想就是通过原型继承多个引用类型的属性和方法。...这个赋值重新更改了SUbType的最初原型,替换成了SuperType实例。这样意味着SuperType实例可以访问所有的属性和方法也存在与SubType.protoype。...这样一来,SubType 的实例不仅能从 SuperType 的实例中继承属性和方法,而且还与 SuperType 的原型挂上了钩。...对于属性和方法一直会持续到原型链末端 原型链虽然是比较强大的继承实现工具,但是它里面所有的引用值都是实例间共享的,而且子类不能向父类传参,一般原型链也不会被单独使用,我们可以通过盗用构造函数配合来解决这些问题

    41020

    JavaScript之面向对象学九(原型式继承和寄生式继承)

    一、原型式继承 该继承模式是由道格拉斯*克罗克福德在2006年提出的实现继承的方法. 模式的基本思路:借助原型可以基于已有的对象创建新的对象,同时还不必因此创建自定义类型。...,也就是说F继承了传入的对象,也相当于用传入的对象重写了F的原型对象 相当于如下代码 /* F.prototype={ name:"张三", friends:["李四","...王五"] };*/ return new F();//返回F对象 注意:此时的原型对象里有一个指向F构造函数的constructor所以这个对象既包括F原型对象也包括F构造函数里面的属性...name="Kobe"; person2.friends.push("Durrant"); alert(person1.friends); //输出:李四,王五,赵六,Durrant 这种继承模式和原型构造函数模式类似...所以根据这个特点,通过更改传入对象的属性值,而省去了创建构造函数的步骤,所以当我们没有必要兴师动众的创建构造函数,只想让一个对象与另一个对象保持类似的情况下,原型继承是完全可以胜任的!

    58870

    JS原型继承和类式继承

    原型最后指向的是null。我们说的原型继承,就是将父对像的方法给子类的原型。子类的构造函数中不拥有这些方法和属性。...所以很显然只能通过中间层才能使得child和father保持为独立的对象。 对比 和原型对比起来,构造函数(类)式继承有什么不一样呢?...组合模式 另外的一种模式,是结合类继承和原型继承的各自优点来进行对父类的继承。用类式继承属性,而原型继承方法。这种模式避免了属性的公用,因为一般来说,每一个子类的属性都是私有的,而方法得到了统一。...他说:“new关键字掩盖了JavaScript中真正的原型继承,使得它更像是基于类的继承。其实new关键字只是Javascript在为了获得流行度而加入与Java类似的语法时期留下来的一个残留物”。...从这里,我们也可以看到类继承和原型基础的一些区别。 结论 原型继承比较符合js这种语言的特点。因为它本身就是js强大的原型的一部分。

    3.5K90
    领券