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

js object 继承

JavaScript中的对象继承是一种机制,它允许一个对象(子对象)继承另一个对象(父对象)的属性和方法。这种机制在JavaScript中是通过原型链实现的。

基础概念

在JavaScript中,每个对象都有一个内部属性[[Prototype]],它指向另一个对象,即该对象的原型。当我们试图访问一个对象的属性或方法时,如果该对象本身没有这个属性或方法,JavaScript会沿着原型链向上查找,直到找到该属性或方法,或者到达原型链的末端(即null)。

继承的优势

  1. 代码复用:子对象可以复用父对象的属性和方法,减少重复代码。
  2. 扩展性:可以在子对象上添加新的属性和方法,或者重写父对象的方法,实现功能的扩展和定制。
  3. 维护性:修改父对象的属性和方法会影响所有继承自它的子对象,便于统一维护。

类型

JavaScript中的继承主要有以下几种类型:

  1. 原型链继承:通过将子对象的[[Prototype]]指向父对象来实现继承。
  2. 构造函数继承:通过在子构造函数中调用父构造函数来实现继承。
  3. 组合继承:结合原型链继承和构造函数继承的优点,实现更完善的继承机制。
  4. 原型式继承:通过创建一个临时的构造函数,并将传入的对象作为这个构造函数的原型,然后返回这个临时构造函数的实例来实现继承。
  5. 寄生式继承:在原型式继承的基础上,对创建的对象进行扩展,增加新的属性和方法。
  6. 寄生组合式继承:结合寄生式继承和组合继承的优点,被认为是实现继承的最佳方式。

应用场景

  • 创建具有相似功能的对象:比如创建一系列具有相似属性和方法的用户界面组件。
  • 框架和库的设计:许多JavaScript框架和库利用继承来构建复杂的组件和插件系统。
  • 面向对象编程:在JavaScript中实现类和对象的继承,模拟传统面向对象语言中的继承机制。

示例代码

以下是一个简单的原型链继承示例:

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

Animal.prototype.sayName = function() {
  console.log('My name is ' + this.name);
};

function Dog(name, breed) {
  Animal.call(this, name); // 调用父类构造函数
  this.breed = breed;
}

// 设置Dog的原型为Animal的实例,实现继承
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog; // 修复构造函数指向

Dog.prototype.sayBreed = function() {
  console.log('My breed is ' + this.breed);
};

var myDog = new Dog('Buddy', 'Golden Retriever');
myDog.sayName(); // 输出: My name is Buddy
myDog.sayBreed(); // 输出: My breed is Golden Retriever

遇到的问题及解决方法

问题:原型链继承可能会导致不必要的属性共享,尤其是当父对象的属性是引用类型时。

解决方法:使用组合继承或寄生组合式继承,通过在子构造函数中调用父构造函数来避免这个问题。

代码语言:txt
复制
function inheritPrototype(subType, superType) {
  var prototype = Object.create(superType.prototype); // 创建对象
  prototype.constructor = subType; // 增强对象
  subType.prototype = prototype; // 指定对象
}

// 父类
function SuperType(name) {
  this.name = name;
  this.colors = ['red', 'blue', 'green'];
}

SuperType.prototype.sayName = function() {
  console.log(this.name);
};

// 子类
function SubType(name, age) {
  SuperType.call(this, name); // 第二次调用SuperType()
  this.age = age;
}

// 继承方法
inheritPrototype(SubType, SuperType);

SubType.prototype.sayAge = function() {
  console.log(this.age);
};

var instance1 = new SubType('Evan', 18);
instance1.colors.push('black');
console.log(instance1.colors); // ['red', 'blue', 'green', 'black']
instance1.sayName(); // Evan
instance1.sayAge(); // 18

var instance2 = new SubType('Nicholas', 29);
console.log(instance2.colors); // ['red', 'blue', 'green']
instance2.sayName(); // Nicholas
instance2.sayAge(); // 29

在这个例子中,SubType的每个实例都有自己的colors属性副本,避免了引用共享的问题。

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

相关·内容

JS 继承

Component, // ... } // 使用 class index extends React.Component{ // ... } React github源码 面试官可以顺着这个问 JS...__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } // 寄生组合式继承的核心 function...Child.sayHello(); // hello child.sayName(); // my name is Child child.sayAge(); // my age is 18 如果对JS...推荐阅读JS继承相关的书籍章节 《JavaScript高级程序设计第3版》第6章——面向对象的程序设计 6种继承的方案,分别是原型链继承、借用构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承...上卷第6章——行为委托和附录A(ES6中的class) 总结 继承对于JS来说就是父类拥有的方法和属性、静态方法等,子类也要拥有。

2.9K32
  • js实现继承

    js实现继承 经典继承(原型链) 缺点:过多的继承了没用的属性 Grandfather.prototype.lastName = 'zhang' function Grandfather() {...father function Son() { this.hobby = 'game' } var son = new Son() console.log(son); ​ son只想要继承...grandfather的lastName属性,但是由于原型链的关系,造成了son既会继承grandfather自神的东西,grandfather的原型的东西,father自身的东西和father原型上的东西...,造成了不必要的继承 共享原型 本质:重写原型对象 优点:只会继承父的原型,不会继承父原本自带的属性或方法(只有调用new Father()才会继承自身的东西) 缺点:给本身的原型添加属性或方法时,会把继承的那个原型也修改了...) 雏形 本质:重写原型对象 优点:只会继承父的原型,不会继承父原本自带的属性或方法(只有调用new Father()才会继承自身的东西) 缺点:1,这样继承后即使修改了son的原型也不会修改father

    5.3K20

    JS原型继承和类式继承

    类式继承(构造函数) JS中其实是没有类的概念的,所谓的类也是模拟出来的。特别是当我们是用new 关键字的时候,就使得“类”的概念就越像其他语言中的类了。...通过在浏览器中打印man我们就可以查看各个原型的继承关系。 ? 可以看到逐级的关系child->object(father实例化的对象)->father。...child是通过中间层继承了father的原型上的东西的。但是为什么中间还有一层object呢,为什么不把child.prototype = father.prototype。...作者推荐我们使用Object.create方法创建或者实例化对象。露珠做过测试,使用new和使用object.create方法都是将对象添加到原型上去。...从这里,我们也可以看到类继承和原型基础的一些区别。 结论 原型继承比较符合js这种语言的特点。因为它本身就是js强大的原型的一部分。

    3.5K90

    JS继承机制总结

    JS继承机制总结 继承就是子类可以使用父类的所有功能,并且对这些功能进行扩展。 JS继承机制主要为原型链继承、构造函数继承、组合继承、寄生继承、寄生组合继承、原型式继承和混合式继承。...}   Child.prototype = Object.create(Parent.prototype) 复制代码 代码实例 function Parent() { this.name =...function createAnother (original) {    var clone = Object.create(original);; // 通过调用 Object.create()...//在这边,我们需要用到`ES6`中的方法`Object.assign()`。 //它的作用就是可以把多个对象的属性和方法拷贝到目标对象中,若是存在同名属性的话,后面的会覆盖前面。...(Parent.prototype) Object.assign(Child.prototype, OtherParent.prototype) Child.prototype.constructor

    1.6K10

    Java类是如何默认继承Object的?

    前言 学过Java的人都知道,Object是所有类的父类。但是你有没有这样的疑问,我并没有写extends Object,它是怎么默认继承Object的呢?...那么今天我们就来看看像Java这种依赖于虚拟机的编程语言是怎样实现默认继承Object的,以及Java编译器和JVM到底是如何做的?...继承自Object验证 首先我们来验证一下Object是不是所有类的父类,随便新建一个Java类,如下图: ?...另外,当A类继承MyClass类时,通过打点也可以调到Object内的方法,这是继承的传递,好比Object是MyClass的“父亲”,MyClass是A类的“父亲”,Object是A类的“爷爷”,间接的继承了...因此,Object是超类,是所有类的父类。 推测可能的原因 要了解Java类是如何默认继承Object的?的原因其实并不需要知道JVM的实现细节。只需了解一下对于这种虚拟机程序的基本原理即可。

    1.8K30

    python3--object类,继承与派生,super方法,钻石继承问题

    __bases__) 执行结果,可以看到A的父类为object,在python3中,只有新式类,默认继承object类 ( 上面代码的执行步骤 1 创建了一个空的对象 2 调用init方法 -- class...执行了父类object的__init__方法 3 将初始化之后的对象返回调用出 在python3中所有的类都继承了object类 查看object的源码 ?...多继承 新式类(也叫钻石继承) ?...'>] 在python2.x中,经典类多继承使用深度优先原则 在python2.x中,不手动继承object类,都属于经典类 ?...经典类:在python2.x版本才存在,且必须不继承object 遍历的时候遵循深度优先算法 没有mro方法 没有super()方法 新式类:在python2.x版本中,需要继承object,才是新式类

    1.1K10

    js Object.defineProperty()详解

    要修改属性的默认特性,就必须使用 Object.defineProperty()方法 ;在了解Object.defineProperty()之前,需要先明白对象属性的一些特性,明白了这些特性之后,对Object.defineProperty...Object.defineProperty() Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象; 语法: Object.defineProperty...(object,prop,descript) Object.defineProperty()接收三个参数: object: 要添加或者修改属性的目标对象; prop: 要定义或修改属性的名称; descript...定义多个属性Object.defineProperties() 在一个对象上同时定义多个属性的可能性是非常大的。...读取属性的特性Object.getOwnPropertyDescriptor() Object.getOwnPropertyDescriptor()方法接收两个参数:属性所在的对象和要取得其描述符的属性名

    2.4K20

    js各种继承方式汇总

    js中的各种继承实现汇总 首先定义一个父类: function Animal(name) { this.name = name || '动物' this.sleep = function ()...方式) 特点: 1、子类的构造中进行父类构造的调用 优点: 1、实现了多继承,想继承哪个直接在子类构造里面call或者apply哪个就行 2、避免所有子类实例共享父类引用属性问题 3、创建子类实例时...,可以向父类传递参数 缺点: 1、没用到原型,只是单纯继承了父类的实例属性及方法 2、没继承原型上的属性及方法 3、每个子类都有父类方法属性的副本,影响性能,没有实现父类函数复用 function...(暴力继承) 特点: 1、子类的构造中强制拷贝父类原型上的属性或方法 优点: 1、可以多重继承 缺点: 1、效率较低,内存占用高 2、不能继承父类不可枚举的属性(不能用for in遍历的)...Animal) // false 组合继承(构造继承+原型链继承) 特点: 1、组合构造继承和原型链继承 优点: 1、可以继承实例属性/方法,也可以继承原型属性/方法 2、既是子类的实例,

    2.2K70
    领券