javascript基于原型链的继承及call和apply函数用法分析

JavaScript基于原型链的继承

什么是继承

在面向对象编程中,继承是一种允许新对象获取现有对象的属性和方法的机制。它允许我们创建继承现有对象的新对象,从而减少代码重复,增加代码可重用性。

JavaScript中基于原型链的继承

在JavaScript中,没有像其他语言一样的类和接口的概念,继承通过原型链来实现。每个对象都有一个原型对象,原型对象又有自己的原型对象,形成一个链式结构,最后的节点是null。

当访问一个对象的属性或方法时,如果该对象本身没有,它会沿着原型链向上查找,直到找到该属性或方法或者查找到null为止。

实现方式

JavaScript中实现继承可以通过以下几个方式:

1.原型链继承

原型链继承是将子类的原型指向父类的实例来实现继承,子类的实例就可以使用父类的属性和方法。原型链继承的一个缺点是由于所有子类的实例共享同一个父类实例,因此一个子类实例中的数据改变了,其他子类实例的数据也会被改变。

function Parent(name) {
    this.name = name;
}
Parent.prototype.getName = function() {
    console.log(this.name);
}

function Child(name) {
    this.name = name;
}
Child.prototype = new Parent();

var child1 = new Child('child1');
var child2 = new Child('child2');
child1.getName(); // 输出:child1
child2.getName(); // 输出:child2

console.log(child1 instanceof Child); // 输出:true
console.log(child1 instanceof Parent); // 输出:true

2.借用构造函数继承

借用构造函数继承是通过在子类构造函数中调用父类的构造函数来实现继承。利用call或apply方法可以实现借用构造函数继承。借用构造函数继承的一个缺点是父类的原型对象中定义的方法无法被子类继承。

function Parent(name) {
    this.name = name;
    this.getName = function() {
        console.log(this.name);
    }
}

function Child(name) {
    Parent.call(this, name);
}

var child = new Child('child');
child.getName(); // 输出:child

console.log(child instanceof Child); // 输出:true
console.log(child instanceof Parent); // 输出:false

3.组合继承

组合继承是同时使用上面两种方式实现继承。通过原型链继承父类原型对象中的属性和方法,再通过借用构造函数继承父类中的属性和方法。组合继承既可以继承原型对象中的方法,又可以继承构造函数中的属性,但它也有一个缺点是调用了两次父类的构造函数。

function Parent(name) {
    this.name = name;
}
Parent.prototype.getName = function() {
    console.log(this.name);
}

function Child(name) {
    Parent.call(this, name);
}
Child.prototype = new Parent();

var child = new Child('child');
child.getName(); // 输出:child

console.log(child instanceof Child); // 输出:true
console.log(child instanceof Parent); // 输出:true

call和apply函数用法分析

callapply都是用来动态改变函数运行时的this绑定的。

call函数

call函数的语法格式:function.call(thisArg, arg1, arg2, ...)

其中:

  • thisArg表示当前函数运行时的this绑定对象
  • arg1, arg2, ...表示传递给当前函数的参数列表,多个参数之间用逗号分隔

通过call函数,我们可以改变函数运行时的this绑定对象。

function greet(word) {
    console.log(word + ',' + this.name);
}

var person = { name: 'Jack' };
greet.call(person, 'Hello'); // 输出:Hello,Jack

apply函数

apply函数的语法格式:function.apply(thisArg, args)

其中:

  • thisArg表示当前函数运行时的this绑定对象
  • args表示传递给当前函数的参数列表,以数组的形式传递

通过apply函数,我们可以将数组作为参数传递给函数。

function greet(word1, word2) {
    console.log(word1 + ',' + word2 + ',' + this.name);
}

var person = { name: 'Jack' };
greet.apply(person, ['Hello', 'Hi']); // 输出:Hello,Hi,Jack

示例说明

示例1

下面是一个继承的例子,利用函数的继承可以减少代码重复。

function Animal(name) {
    this.name = name;
}
Animal.prototype.getSound = function() {
    console.log('Animal sound');
}

function Dog(name) {
    Animal.call(this, name);
}
Dog.prototype = new Animal();
Dog.prototype.getSound = function() {
    console.log('Wang Wang');
}

var dog = new Dog('Tom');
dog.getSound(); // 输出:Wang Wang
console.log(dog.name); // 输出:Tom

示例2

下面是一个使用call函数的例子,将一个对象的方法应用到另一个对象上。

function greet(word) {
    console.log(word + ',' + this.name);
}

var obj1 = { name: 'Jack' };
var obj2 = { name: 'Tom' };

greet.call(obj1, 'Hello'); // 输出:Hello,Jack
greet.call(obj2, 'Hi'); // 输出:Hi,Tom

通过上面的例子,我们可以看到call函数的灵活性,它可以将对象的方法应用到另一个对象上。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:javascript基于原型链的继承及call和apply函数用法分析 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • maven配置文件pom增加变量取版本号方式

    Maven 是一个强大的 Java 项目构建工具,为了方便地管理和构建项目,Maven 在项目根目录下(Maven 3 的版本中叫做 pom.xml)提供了一个 pom.xml 的配置文件,其中可以定义项目的名称、描述、依赖关系等信息。 在 pom.xml 文件中,可以配置 variable(变量) 来存放一些常量,例如版本号、路径等等,以减少硬编码并方便维…

    Java 2023年5月20日
    00
  • 微信公众号服务号推送模板消息设置方法(后端java)

    下面是详细的攻略: 微信公众号服务号推送模板消息设置方法 开启模板消息功能 要使用模板消息功能,首先需要在公众号后台开启该功能。具体操作步骤如下: 登录公众号后台,在左侧菜单栏中选择“开发者工具”。 点击页面上方的“接口权限”选项卡,找到“模板消息”并开启该功能。 开启模板消息功能后,需要到“模板消息”选项中添加至少一个消息模板。在添加模板时需要提供模板的标…

    Java 2023年5月20日
    00
  • 使用JDBC在MySQL数据库中如何快速批量插入数据

    使用JDBC在MySQL数据库中进行批量插入数据可以大大提高数据插入的效率。以下是详细步骤: 1.导入MySQL JDBC驱动 首先需要在Java项目中导入MySQL JDBC驱动包,这里以MySQL 8为例,可以从以下链接中下载:https://dev.mysql.com/downloads/connector/j/ 2.创建JDBC连接 使用JDBC连接…

    Java 2023年6月16日
    00
  • Spring整合Mybatis思路梳理总结

    Spring整合Mybatis思路梳理总结 1. 引入相关依赖 首先,在Maven或Gradle中引入Spring和Mybatis相关的依赖: <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</arti…

    Java 2023年5月19日
    00
  • Java Apache Commons报错“TimeoutException”的原因与解决方法

    “TimeoutException”是Java的ApacheCommons类库中的一个异常,通常由以下原因之一引起: 网络连接超时:如果网络连接超时,则可能会出现此异常。例如,可能会尝试连接到不可用的主机或端口。 线程等待超时:如果线程等待超时,则可能会出现此异常。例如,可能会等待某个资源的可用性,但超时时间已过。 以下是两个实例: 例1 如果网络连接超时,…

    Java 2023年5月5日
    00
  • SpringBoot扩展外部化配置的原理解析

    下面我为你详细讲解“SpringBoot扩展外部化配置的原理解析”的攻略。 1. 理解SpringBoot配置管理流程 SpringBoot使用YAML或properties格式的文件来管理应用程序所需的各种配置信息。它们可以分为应用表现配置和逻辑配置两类,其中应用表现配置是指一些与应用程序用户直接交互的配置,例如网站标题和页脚等。逻辑配置是指一些与应用程序…

    Java 2023年5月31日
    00
  • Java读取邮件的方法

    下面是详细讲解Java读取邮件的方法的完整攻略。 1. 使用JavaMail API JavaMail API 是一组用于发送、接收和管理电子邮件的Java类库。通过JavaMail API,我们可以使用Java读取邮件。 步骤: 导入JavaMail API jar包,例如:javax.mail.jar,可以从这里下载。 创建Session实例,用于连接邮…

    Java 2023年5月20日
    00
  • 使用java NIO及高速缓冲区写入文件过程解析

    使用Java NIO及高速缓冲区写入文件可以提高文件写入的效率,下面我来为大家详细讲解该过程的完整攻略。 1. Java NIO简介 Java NIO(New IO)是Java SE 1.4版本引入的非阻塞I/O API,它比原来的I/O API(现在称为IO)更快、更灵活、更可扩展。NIO由以下几个核心组件组成: Buffer(缓冲区):NIO中的所有I/…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部