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日

相关文章

  • 一文秒懂通过JavaCSV类库读写CSV文件的技巧

    一文秒懂通过JavaCSV类库读写CSV文件的技巧 什么是CSV文件 CSV文件(Comma-Separated Values,逗号分隔值)是一种常见的文本格式,用来存储结构化数据,其每行都表示一条记录,每个记录使用逗号或其他分隔符分割字段,每个字段的值可以用引号括起来。 例如,以下CSV文件表示了三个人的基本信息: Name,Age,Gender &quo…

    Java 2023年5月19日
    00
  • Spring Bean创建流程分析讲解

    关于Spring Bean创建流程分析的完整攻略,可以从以下几个方面进行讲解: Spring Bean创建流程 Spring Bean的创建流程主要分为以下5个步骤: 定位阶段(Location):Spring通过配置文件或注解等方式确定Bean定义; 加载阶段(Load):将Bean定义解析成Bean对象,并注册到容器中; 实例化阶段(Instantiat…

    Java 2023年5月31日
    00
  • SpringBoot整合Mybatis注解开发的实现代码

    接下来我将以以下步骤为例,详细讲解SpringBoot整合Mybatis注解开发的实现代码: 配置Mybatis 首先,在Spring Boot配置文件中添加Mybatis的相关配置,如下所示: mybatis: mapper-locations: classpath:mapper/*.xml configuration: map-underscore-to…

    Java 2023年5月20日
    00
  • Java Spring分别实现定时任务方法

    Java Spring 是一个开源的全栈轻量级应用框架,可以通过 Spring 框架实现定时任务即在指定时间轮询执行某个任务或在固定时间执行某个任务。下面详细介绍一下 Java Spring 分别实现定时任务的方法: 1. Spring Schedule 注解方式 这种方法主要使用在方法上添加注解,从而使得方法在特定的时间点或者时间间隔执行。 在Spring…

    Java 2023年6月1日
    00
  • Java实现权重随机算法详解

    Java实现权重随机算法详解 在实际开发中,我们经常需要对一堆数据进行随机选择,但是在某些场景下,我们需要对数据进行加权处理,比如在广告投放中,每个广告都有不同的的权重,需要按照权重进行选择。这个时候,我们就需要使用权重随机算法。下面我们就来详细讲解Java实现权重随机算法: 概述 权重随机算法是一种按照权重随机选择的算法。它的原理很简单,就是将每个数据的权…

    Java 2023年5月19日
    00
  • 正则表达式匹配各种特殊字符

    正则表达式是一种用来匹配字符串的语言,它可以帮助我们在字符串中查找匹配特定模式的文本,包括各种特殊字符。下面是正则表达式匹配特殊字符的完整攻略: 1. 转义特殊字符 正则表达式中有些字符具有特殊的含义,比如”.”、”|”等,如果我们需要匹配这些特殊字符本身,需要在前面加上”\”来进行转义。例如: import re str = "The price…

    Java 2023年5月20日
    00
  • 简单了解Java关键字throw和throws的区别

    简单了解Java关键字throw和throws的区别 在Java中,throw和throws是两个与异常相关的关键字,它们的作用和使用场景不同,但经常容易混淆。 throw关键字 throw关键字用于抛出一个异常对象。我们可以在代码中手动抛出一个异常对象并且将其名称直接传递给throw语句。抛出异常后,程序会立即终止当前的语句执行,并开始执行异常处理流程。 …

    Java 2023年5月25日
    00
  • Java运行时动态生成对象的方法小结

    下面是详细的Java运行时动态生成对象的方法攻略。 1. 简介 在Java中,动态生成对象可以使用Class类的newInstance方法实现。新的创建对象方式是在运行时实现的,因此被称为Java运行时动态生成对象。使用这种方式可以避免在编译时给出类名的麻烦,只需要在运行时确定需要实例化的类名即可。 2. 方法使用 Class类是Java中所有类的超类,它通…

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