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

js继承调用链

在JavaScript中,继承调用链是指当访问一个对象的属性或方法时,JavaScript引擎会沿着原型链(prototype chain)查找这个属性或方法,直到找到为止,或者到达原型链的末端(即null)。

基础概念

  1. 原型对象(Prototype):每个JavaScript对象都有一个原型对象,它是一个普通的对象,包含了可以被其他对象共享的属性和方法。
  2. 原型链(Prototype Chain):当访问一个对象的属性时,如果对象本身没有这个属性,那么JavaScript引擎就会去这个对象的原型对象上找,如果还没有,就继续去原型对象的原型对象上找,以此类推,直到找到这个属性或者到达原型链的末端。

相关优势

  • 代码复用:通过原型链,可以实现属性和方法的共享,从而减少内存消耗。
  • 继承:子类可以继承父类的属性和方法,实现代码的扩展和重用。

类型

  • 构造函数继承:通过Parent.call(this, ...)的方式,在子类构造函数中调用父类构造函数。
  • 原型链继承:将子类的原型对象设置为父类的一个实例。
  • 组合继承:结合构造函数继承和原型链继承的优点。
  • ES6类继承:通过classextends关键字实现更简洁明了的继承方式。

应用场景

  • 当需要创建多个具有相同属性和方法的对象时,可以使用继承来避免重复代码。
  • 当需要扩展已有类的功能时,可以通过继承来实现。

问题及解决方法

问题:在继承调用链中,为什么会出现undefined

原因:这通常是因为在访问一个不存在的属性或方法时,JavaScript引擎会沿着原型链一直查找,直到找到这个属性或方法或者到达原型链的末端。如果到达末端还没有找到,就会返回undefined

解决方法:确保要访问的属性或方法在原型链中的某个对象上存在。可以使用hasOwnProperty方法来检查对象本身是否具有某个属性,而不是在原型链上。

示例代码(ES6类继承):

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

  sayHello() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

class Child extends Parent {
  constructor(name, age) {
    super(name); // 调用父类构造函数
    this.age = age;
  }

  sayAge() {
    console.log(`I am ${this.age} years old`);
  }
}

const child = new Child('Alice', 10);
child.sayHello(); // 输出:Hello, my name is Alice
child.sayAge(); // 输出:I am 10 years old

在这个例子中,Child类通过extends关键字继承了Parent类。Child类的实例可以访问Parent类的属性和方法,同时还可以访问自己的属性和方法。

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

相关·内容

【JS精粹】原型链继承和构造函数继承的 “毛病”

好了,有这个认知基础,我们再看原型继承。 原型链继承 原型继承最直接的一种实现就是:原型链继承 ECMA-262 把原型链定义为 ECMAScript 的主要继承方式。...__proto__ === null // true 当然,我们并不是来讲原型链的。重点是:点出原型链继承的“问题”!!...构造函数继承 构造函数继承,也叫做:“盗用构造函数”,“对象伪装”或“经典继承”。 基本思路:在子类构造函数中用 apply()和 call()方法调用父类构造函数。...思路是:使用原型链继承原型上的属性和方法,而通过构造函数继承实例属性。...说实话,JS 继承真的很奇怪。。。并不是面向对象语言,又要通过原型链去模拟面向对象,真的很多小坑的点需要去注意。

1.3K20
  • js的this、call、apply、bind、继承、原型链

    本文来自我的github 0.前言 这些都是js基础进阶的必备了,有时候可能一下子想不起来是什么,时不时就回头看看基础,增强硬实力。...首先,js没有严格意义上的子类父类,实现继承是依靠原型链来实现类似于所谓的类的效果。...因为属性查找是按照原型链查找,先查找自身再查找原型链,找到为止。用了等号,先给自身赋值,所以自身赋值成功了也不会继续去原型链查找。...但是实例化都会调用两次构造函数,new和call 3.3Object.create继承(原型继承) 这样子,可以在两个prototype中间加上一个中介F类,使得子类不会污染父类,子类A是父类B继承而来...构造函数是B 附上原型链图解:(注意终点是null,中间的都是正常new构造,没有改写prototype)

    97410

    JS原型链与继承别再被问倒了

    原文:详解JS原型链与继承 摘自JavaScript高级程序设计: 继承是OO语言中的一个最为人津津乐道的概念.许多OO语言都支持两种继承方式: 接口继承 和 实现继承 .接口继承只继承方法签名,而实现继承则继承实际的方法....由于js中方法没有签名,在ECMAScript中无法实现接口继承.ECMAScript只支持实现继承,而且其 实现继承 主要是依靠原型链来实现的....组合继承 组合继承, 有时候也叫做伪经典继承,指的是将原型链和借用构造函数的技术组合到一块,从而发挥两者之长的一种继承模式....组合继承最大的问题就是无论什么情况下,都会调用两次父类构造函数: 一次是在创建子类型原型的时候, 另一次是在子类型构造函数内部. 寄生组合式继承就是为了降低调用父类构造函数的开销而出现的 ....,第一次调用Father() this.age = age; } extend(Son,Father)//继承父类方法,此处并不会第二次调用Father() Son.prototype.sayAge =

    62150

    js继承

    类式继承 1.最常用的继承组合模式 —— 借用构造函数 & 设置原型 // 父类 function Parent(name) { this.name = name;...// 设置原型 继承父类this属性以及父类的原型 Child.prototype = new Parent(); 缺点:父构造函数被调用了两次,从而导致同一个属性会被继承两次(this.name...继承了父类自身的属性 继承了父类的原型属性(方法) 基于上面的问题,如果 Child.prototype 不指向 Parent的实例 new Parent(),而是指向 Parent.prototype...原型继承并不涉及到类,这里的对象都是继承自其他对象。...—— 浅复制 & 深复制 继承的目的是为了实现代码复用,所以一个对象要从另一个对象中获取功能,把目标对象的属性和方法复制过来也是一种方法。

    2.6K10

    JS 继承

    子类构造函数 Child继承了父类构造函数 Preant的里的属性。使用 super调用的( ES5则用 call或者 apply调用传参)。也就是图中用不同颜色标记的两条线。...推荐阅读JS继承相关的书籍章节 《JavaScript高级程序设计第3版》第6章——面向对象的程序设计 6种继承的方案,分别是原型链继承、借用构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承...上卷第6章——行为委托和附录A(ES6中的class) 总结 继承对于JS来说就是父类拥有的方法和属性、静态方法等,子类也要拥有。...子类中可以利用原型链查找,也可以在子类调用父类,或者从父类拷贝一份到子类等方案。 继承方法可以有很多,重点在于必须理解并熟。 悉这些对象、原型以及构造器的工作方式,剩下的就简单了。...子类构造器里调用父类构造器,继承父类的属性。

    2.9K32

    Javascript 组合继承 原型链继承 寄生继承

    console.log(this.age); }; var instancel = new SubType("Nicholas", 12); SuperType() 该继承通过构造函数继承原型链的方法和父类的属性...,但该方法会有两次调用父类,第一次是在继承原型链,第二次在继承属性。...第二种:原型链继承 //原型式继承实例代码: function createObj(o) {//对传入的对象执行了一次浅复制 function F() {} F.prototype...Lin"; yePs.friends.push("Sari"); console.log(person.friends);//"one,two,van,Rob,Sari" 这个没什么,Js...第三种:寄生式继承 在第一种的方法上,我们在第一次调用父类,也就是继承原型的时候,实际上只需要父类的原型副本,那么取得副本,也就省去了这一次调用。 该继承技术是最常用的。

    1.1K40

    JS中的面向对象、原型、原型链、继承总结大全

    继承 什么是原型链 ECMA中继承的主要方法就是通过原型链,主要是一个原型对象等于另一个类型的实例,由于实例内部含有一个指向构造函数的指针,这时候相当于重写了该原型对象,此时该原型对象就包含了一个指向另一个原型的指针...属性查找机制 js中实例属性的查找,是按照原型链进行查找,先找实例本身有没有这个属性,如果没有就去查找查找实例的原型对象,也就是[[prototype]]属性指向的原型对象,一直查到Object.prototype...__proto__ === Object.prototype); // true 构造函数模式和原型模式组合继承 只通过原型来实现继承,还存在一定问题,所以js中一般通过借用构造函数和原型组合的方式来实现继承...,也是本篇最重要的内容: 1.属性继承 在子构造函数内,使用apply()或call()方法调用父构造函数,并传递子构造函数的this 2.方法继承 使用上文提到的原型链继承,继承父构造器的方法 上代码...方法继承,就是上文讲的到的原型链机制继承,另外可以给子构造函数添加自己的属性和方法。 这就是经典继承,避免了但是使用构造函数或者单独使用原型链的缺陷,成为js中最常用的继承方式。

    1.4K22

    js实现继承

    js实现继承 经典继承(原型链) 缺点:过多的继承了没用的属性 Grandfather.prototype.lastName = 'zhang' function Grandfather() {...grandfather的lastName属性,但是由于原型链的关系,造成了son既会继承grandfather自神的东西,grandfather的原型的东西,father自身的东西和father原型上的东西...,造成了不必要的继承 共享原型 本质:重写原型对象 优点:只会继承父的原型,不会继承父原本自带的属性或方法(只有调用new Father()才会继承自身的东西) 缺点:给本身的原型添加属性或方法时,会把继承的那个原型也修改了...) 原理:在函数里面调用函数,约等于将父里面的代码复制粘贴到子里面,然后通过call将父的this改成子的this 缺点: 不能继承借用的构造函数的原型 每次调用子构造函数都要调用多一次借用的父构造函数...) 雏形 本质:重写原型对象 优点:只会继承父的原型,不会继承父原本自带的属性或方法(只有调用new Father()才会继承自身的东西) 缺点:1,这样继承后即使修改了son的原型也不会修改father

    5.3K20

    this_原型链_继承

    在JS中,这三者都是用来改变函数的this对象的指向,相似点: 1.都是用来改变函数的this对象的指向的。 2.第一个参数都是this要指向的对象。 3.都可以利用后续参数传参。...不同之处:bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。...并解释什么是原型链。...继承就是子类拥有父类的属性和方法。 作用:继承划分了类的层次性,父类代表的是更一般、更泛化的类,而子类则是更为具体、更为细化;继承是实现代码重用、扩展软件功能的重要手段。...this.name); } var p1 = new Person('xuguojun', 25); //这种形式创建的p1本身有name、sex属性,但没有printName方法,但p1能够通过原型链调用

    58220

    JavaScript原型链继承

    当我们在一个对象上调用属性或方法时,如果该对象本身没有该属性或方法,JavaScript会在原型链上继续向上查找,直到找到对应的属性或方法或者到达原型链的末尾。...在Dog构造函数内部,我们没有显式地调用Animal构造函数,而是将Dog的原型指向了一个新的Animal实例。这样,Dog的实例就可以通过原型链继承Animal的属性和方法。...我们可以调用myDog的sleep和bark方法,因为它们是通过原型链继承自Animal和Dog的原型对象。...原型链继承的特点原型链继承具有以下特点:属性和方法的继承:通过原型链继承,子对象可以继承父对象的属性和方法。...这样形成了一个链式结构,可以灵活地调用和扩展父对象的功能。动态性:对原型对象的修改会立即反映在所有继承该原型链的对象上。

    39810

    JS原型继承和类式继承

    类式继承(构造函数) JS中其实是没有类的概念的,所谓的类也是模拟出来的。特别是当我们是用new 关键字的时候,就使得“类”的概念就越像其他语言中的类了。...类式继承是在函数对象内调用父类的构造函数,使得自身获得父类的方法和属性。call和apply方法为类式继承提供了支持。通过改变this的作用环境,使得子类本身具有父类的各种属性。...话说回来,当一个对象需要调用某个方法时,它回去最近的原型上查找该方法,如果没有找到,它会再次往下继续查找。这样逐级查找,一直找到了要找的方法。 这些查找的原型构成了该对象的原型链条。...另外就是类式继承不支持多重继承,而对于原型继承来说,你只需要写好extend对对象进行扩展即可。 组合模式 另外的一种模式,是结合类继承和原型继承的各自优点来进行对父类的继承。...从这里,我们也可以看到类继承和原型基础的一些区别。 结论 原型继承比较符合js这种语言的特点。因为它本身就是js强大的原型的一部分。

    3.5K90

    《JS原理学习 (2) 》深入理解原型链与继承

    ,第二次调用父类构造函数 Super.call(this,name); this.age = age; } // 原型链继承,第一次调用父类构造函数 Sub.prototype = new...第一次调用父类构造函数时: 我们重写了Sub的原型对象,将其指向了Super的实例 此时,父类构造函数实例上的属性和方法会赋值给Sub.prototype 这一次调用就是我们在原型链继承章节所讲的内容,...第二次调用父类构造函数时: 我们在Sub的构造函数内部,使用call会将Super中的属性和方法赋值给Sub的实例上 原型链在搜索属性时,实例上的属性会屏蔽原型链上的属性 因此,第二次调用时,我们就没有必要将构造函数中的属性和方法赋值给...他的高效之处在于只有在实例化时才会调用一次Super构造函数,并且保持原型链的不变。...写在最后 本文为《JS原理学习》系列的第2篇文章,本系列的完整路线请移步:JS原理学习 (1) 》学习路线规划

    31430

    扫码

    添加站长 进交流群

    领取专属 10元无门槛券

    手把手带您无忧上云

    扫码加入开发者社群

    相关资讯

    热门标签

    活动推荐

      运营活动

      活动名称
      广告关闭
      领券