反思原型链

一、原型链基础

JavaScript的原型链是一种从对象到另一个对象的委托关系。它在一个对象的属性找不到时,会沿着原型链往上找指定名称的属性或方法。我们来看一个例子:

function Animal(name){
  this.name = name;
}

Animal.prototype.getName = function(){
  return this.name;
}

function Dog(name){
  this.name = name;
}

Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;

var dog = new Dog('Henry');
console.log(dog.getName()); //输出:Henry

在此代码中,我们定义了Animal和Dog两个构造函数,并且让Dog的原型指向Animal的实例。当我们调用dog.getName()时,JavaScript引擎会在dog对象上查找getName方法,没有找到时会沿着原型链往上找Animal.prototype上的getName方法。

二、改变原型链

在上一个例子中,我们让Dog的原型指向了Animal的实例,在Dog.prototype上定义getName方法。这种方式同样有一些问题:

function Animal(name){
  this.name = name;
}

Animal.prototype.getName = function(){
  return this.name;
}

function Dog(name){
  this.name = name;
}

Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
Dog.prototype.getName = function(){
  return 'My name is ' + this.name;
}

var dog = new Dog('Henry');
console.log(dog.getName()); //输出:My name is Henry

var animal = new Animal('Oscar');
console.log(animal.getName()); //输出:Oscar

在此代码中,我们在Dog.prototype上定义了一个新的getName方法,这会影响到它的父对象Animal.prototype上的getName方法,而且animal对象也会受到影响。

为了避免这种相互污染的问题,我们可以使用Object.create()方法,创建一个新的对象作为原型,并将其赋值给Dog.prototype。

function Animal(name){
  this.name = name;
}

Animal.prototype.getName = function(){
  return this.name;
}

function Dog(name){
  this.name = name;
}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.getName = function(){
  return 'My name is ' + this.name;
}

var dog = new Dog('Henry');
console.log(dog.getName()); //输出:My name is Henry

var animal = new Animal('Oscar');
console.log(animal.getName()); //输出:Oscar

三、继承的多种方式

除了使用原型链实现继承之外,我们还可以使用其他几种方式:构造函数、组合继承、寄生构造函数和组合继承。

1. 构造函数

构造函数是最基本的一种继承方式。它有一些局限性,例如无法访问父对象的属性和方法,但在一些情况下,由于其简单易用,还是有着很大的用武之地。

function Animal(name){
  this.name = name;
  this.getName = function(){
    return this.name;
  }
}

function Dog(name, type){
  this.type = type;
  this.getType = function(){
    return this.type;
  }

  Animal.call(this, name);
}

var dog = new Dog('Henry', 'Poodle');
console.log(dog.getName()); //输出:Henry
console.log(dog.getType()); //输出:Poodle

2. 组合继承

组合继承是指同时采用构造函数和原型链的继承方式。使用该方法,可以避免构造函数和原型链各自的局限性和缺陷。

function Animal(name){
  this.name = name;
}

Animal.prototype.getName = function(){
  return this.name;
}

function Dog(name, type){
  this.type = type;

  Animal.call(this, name);
}

Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
Dog.prototype.getType = function(){
  return this.type;
}

var dog = new Dog('Henry', 'Poodle');
console.log(dog.getName()); //输出:Henry
console.log(dog.getType()); //输出:Poodle

3. 寄生构造函数

寄生构造函数是指在另一个构造函数的基础上增加一些方法或属性,从而达到继承的目的。与传统的构造函数继承相比,寄生构造函数继承的优势在于可以使用闭包,对属性和方法进行封装,从而达到不污染父对象的目的。

function Animal(name){
  this.name = name;
}

Animal.prototype.getName = function(){
  return this.name;
}

function Dog(name, type){
  var self = new Animal(name);

  self.type = type;
  self.getType = function(){
    return this.type;
  }

  return self;
}

var dog = new Dog('Henry', 'Poodle');
console.log(dog.getName()); //输出:Henry
console.log(dog.getType()); //输出:Poodle

4. 组合继承

寄生组合继承也是一种很好的继承方式,它通过借用构造函数继承父对象的属性和方法,和通过原型链继承父对象的原型,达到继承的目的。

function Animal(name){
  this.name = name;
}

Animal.prototype.getName = function(){
  return this.name;
}

function Dog(name, type){
  Animal.call(this, name);
  this.type = type;
}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.getType = function(){
  return this.type;
}

var dog = new Dog('Henry', 'Poodle');
console.log(dog.getName()); //输出:Henry
console.log(dog.getType()); //输出:Poodle

原创文章,作者:TEFJL,如若转载,请注明出处:https://www.506064.com/n/368435.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
TEFJLTEFJL
上一篇 2025-04-12 01:13
下一篇 2025-04-12 01:13

相关推荐

  • 谷歌Axure插件——提高原型设计效率的利器

    一、快速制作自定义组件 1、Axure自带的组件库虽然丰富,但在某些情况下我们需要自己设计一些特殊的组件,而谷歌Axure插件提供了一个轻松快捷的方式。 以设计一个自定义开关组件为…

    编程 2025-04-22
  • 深入解析JavaScript原型链面试题

    JavaScript 是一种弱类型、基于原型的编程语言。原型是 JavaScript 的一项非常重要的特性,也是面试中经常考察的知识点。JS 原型链是基于原型的面向对象编程的基石,…

    编程 2025-03-12
  • 原型与原型链

    一、什么是原型 在JavaScript中,每个对象都有一个指向另一个对象的引用,叫做原型。原型是JavaScript中一个比较重要的概念。 通过使用构造函数创建的对象,会自动拥有一…

    编程 2025-02-24
  • 原型模式的应用场景

    一、单例模式的应用场景 单例模式是一种常见的设计模式,其应用场景也非常广泛。单例模式通常只允许一个实例存在,可以用于创建全局唯一的对象。在使用原型模式实现单例模式时,先创建一个原型…

    编程 2025-02-17
  • js原型链编程,js原型链概念

    本文目录一览: 1、javascript 原型,原型链是什么?有什么特点 2、js原型和原型链的理解是什么? 3、js原型链和继承的理解 4、谈谈对原型链的理解 JS原型链怎么理解…

    编程 2025-01-09
  • java桌面应用程序原型,软件开发 原型

    本文目录一览: 1、Java原型模式 2、Java适合开发桌面应用程序吗? 3、JAVA 怎么把程序做成 桌面应用程序 Java原型模式 不用例子,如果你的某个类在整个工程中只需要…

    编程 2024-12-15
  • 原型网络:从概念到应用

    一、什么是原型网络 原型网络(Prototypical Network)是一种深度学习中用于学习表示空间的神经网络,由于能够处理较小的数据集而被广泛应用于图像分类、目标识别等领域。…

    编程 2024-12-12
  • 软件原型设计详解

    一、软件原型设计工具 软件原型设计是实现产品设计的重要步骤,而软件原型设计工具就是我们能够使用的工具。 目前市面上存在很多软件原型设计工具,比较常见的有: Axure RP Ske…

    编程 2024-11-25
  • c语言中c=a\u003e3,C语言中,函数可以用原型说明,也可用简单说明

    本文目录一览: 1、c语言中 c=”a”是什么意思 2、在c语言中char choose=0是什么意思 3、C语言中 c=’a’, …

    编程 2024-11-08
  • c语言strcmp原型,c语言strcpy函数原型

    本文目录一览: 1、strcmp原理 2、C语言中strcmp函数怎么用啊 3、C语言编程strcmp函数的问题 4、C语言 strcmp(“how”,&#…

    编程 2024-11-05

发表回复

登录后才能评论