详解JavaScript原型与原型链

详解JavaScript原型与原型链

前置知识

在深入讲解JavaScript原型与原型链之前,需要了解以下概念:

  • 对象
  • 构造函数
  • 实例
  • 继承

原型

JavaScript中有一个对象,称为原型对象(prototype object),它指向一个JavaScript对象。每个JavaScript对象都有一个原型对象。

在对象定义时,可以通过Object.create()方法,创建一个新对象,并指定newObject的原型对象为someObject

var someObject = {
  a: 1
};

var newObject = Object.create(someObject);

在上述代码中,newObject的原型对象为someObject

原型链

原型对象也可以有自己的原型。这种关系可以形成链状结构,被称作原型链(prototype chain)。

如果在一个对象中查找属性或方法时,找不到,它会沿着原型链一直向上查找,直到找到匹配的属性或方法或者查找到原型链的顶部,也就是Object.prototype为止,如果在整个原型链上都没找到,返回undefined。

构造函数

构造函数(constructor)是通过new关键字创建对象的特殊函数。构造函数可以用来创建特定类型的对象,相当于类的概念。

在构造函数中,可以使用this关键字给对象添加属性和方法,同时可以使用new关键字创建实例。

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

var p = new Person('张三');

在上述代码中,Person可以看作是一个构造函数,可以通过new关键字创建实例。p就是一个实例。

实例属性与原型属性

构造函数中定义的属性和方法,每一个实例都有一个独立的副本,称之为实例属性或方法。而通过原型对象定义的属性和方法,则被所有实例共享,称之为原型属性或方法。

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

Person.prototype.sayHello = function() {
  console.log('Hello');
};

var p = new Person('张三');
var q = new Person('李四');

p.sayHello(); // 输出 'Hello'
q.sayHello(); // 输出 'Hello'

在上述代码中,sayHello方法是定义在Person的原型对象上的,所以被所有实例共享。

对象继承

要实现继承,需要使用到原型链。

在JavaScript中,每个对象都有一个原型对象,可以通过重写对象的原型对象来实现继承。我们可以通过构造函数中的Object.create方法,将父类的原型对象作为参数传入,生成一个新的对象,将这个新的对象作为子类的原型对象。

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

Person.prototype.sayHello = function() {
  console.log('Hello');
};

function Student(name, grade) {
  Person.call(this, name);
  this.grade = grade;
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

Student.prototype.sayGoodbye = function() {
  console.log('Goodbye');
};

var s = new Student('张三', '大一');

s.sayHello(); // 输出 'Hello'
s.sayGoodbye(); // 输出 'Goodbye'

在上述代码中,Person是父类,Student是子类,Student通过Object.create(Person.prototype)来实现继承。

示例说明

示例1

现在有一个 Car 构造函数,它的原型对象上有一个 brand 属性,同时原型对象上还有一个 run 方法,可以让汽车行驶。现在我们创建了一个 Honda 的实例,用 console.log 依次输出它的属性和方法。

function Car() {}

Car.prototype.brand = 'Honda';

Car.prototype.run = function() {
  console.log('The car is running');
};

var honda = new Car();

console.log(honda.brand); // 输出 'Honda'
honda.run(); // 输出 'The car is running'

在上面的代码中,hondaCar 的一个实例,它继承了 Car 的原型对象上的 brand 属性和 run 方法。

示例2

现在有一个 Animal 构造函数,它拥有一个 type 属性。我们需要编写一个 Cat 构造函数,使它继承 Animal,同时为 Cat 添加一个 name 属性。创建两个 Cat 的实例,用 console.log 依次输出它们的属性。

function Animal() {}

Animal.prototype.type = '动物';

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

Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;

var cat1 = new Cat('小白');
var cat2 = new Cat('小黑');

console.log(cat1.type); // 输出 '动物'
console.log(cat1.name); // 输出 '小白'

console.log(cat2.type); // 输出 '动物'
console.log(cat2.name); // 输出 '小黑'

在上述代码中,Cat 通过 Object.create(Animal.prototype) 来实现继承 Animal 的原型对象,并重写它的构造函数。cat1cat2Cat 的两个实例,它们都拥有 Animaltype 属性和 Catname 属性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解JavaScript原型与原型链 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • Vue实现路由跳转和嵌套

    下面我将详细讲解如何使用Vue实现路由跳转和嵌套。 使用Vue实现路由跳转和嵌套 Vue作为一款主流的前端框架,提供了非常方便的路由管理方式。我们可以通过Vue Router插件来实现路由相关的操作,包括路由跳转和嵌套等。 安装Vue Router插件 首先,我们需要安装Vue Router插件。可以通过Vue CLI工具来创建一个项目,并在项目中安装Vue…

    JavaScript 2023年6月11日
    00
  • 详解JS数据类型的值拷贝函数(深拷贝)

    以下是详解JS数据类型的值拷贝函数(深拷贝)的攻略: 什么是深拷贝 在 JS 中,我们把变量分为两类:基础类型和引用类型。基本类型的值直接存储在栈(stack)中,而引用类型的值存储在堆(heap)中,变量实际上是一个指针指向对应的地址。因此,基础类型变量的修改不影响其他变量,而引用类型变量的修改会影响所有指向同一地址的变量。而深拷贝就是将原始数据类型和引用…

    JavaScript 2023年6月10日
    00
  • 浅谈Vue单页面做SEO的四种方案

    方案一:使用预渲染 预渲染是一种将 SPA 应用在服务器端对页面进行完全渲染,然后将渲染好的 HTML 文件返回给客户端的技术。适用于 SEO 需求比较简单的情况。具体步骤如下: 安装插件 prerender-spa-plugin ,并在 webpack 配置中进行设置; 对于每个需要预渲染的路由,设置它们对应的 meta 信息,这些 meta 熟悉在 he…

    JavaScript 2023年6月11日
    00
  • ASP.NET 窗体间传值的方法

    ASP.NET是一种基于Web应用程序的框架,可以轻松实现Web开发,并提供了多种窗体间传值的方法。 一、Query String Query String是通过在URL上添加查询字符串的方法。例如,可以使用以下代码在源页面中将值传递到目标页面: string url = "targetPage.aspx?name=" + txtName…

    JavaScript 2023年6月11日
    00
  • js 效率组装字符串 StringBuffer

    首先,需要明确的是,JavaScript 中没有对应 Java 中 StringBuffer 的类。但是,我们可以使用数组来完成字符串的效率组装,具体步骤如下: 定义空数组 const sb = []; 将要组装的字符串一段一段地推进数组里,并使用join()方法将数组连接成字符串 sb.push(‘hello’); sb.push(‘world’); co…

    JavaScript 2023年5月28日
    00
  • JS 面向对象的5钟写法

    下面我来详细讲解一下“JS 面向对象的5种写法”的完整攻略。 前言 在JavaScript中,常用的面向对象的写法有5种,分别是原型链、Class、工厂模式、构造函数和混合模式。下面我们来分别介绍这五种写法。 1. 原型链 在JavaScript中,每个对象都有一个原型(也就是一个或者多个prototype)。使用原型链实现的继承是通过将一个类型的实例设置为…

    JavaScript 2023年5月27日
    00
  • 解析ajaxFileUpload 异步上传文件简单使用

    解析ajaxFileUpload 异步上传文件简单使用攻略 异步上传文件简介 在传统的表单提交中,如果需要上传文件,则需要重新加载整个页面,用户体验并不好,而且上传大文件还会影响页面的响应速度。而异步上传则是采用ajax技术,实现上传文件的同时不刷新整个页面,从而提升用户体验。 ajaxFileUpload 简介 在实现异步上传功能的过程中,ajaxFile…

    JavaScript 2023年6月11日
    00
  • 用javascript获取当页面上鼠标光标位置和触发事件的对象的代码

    获取鼠标光标位置和触发事件对象是Javascript开发中常用的技能,下面将介绍如何使用Javascript获取鼠标光标位置和事件对象。 获取鼠标光标位置 获取鼠标光标位置可以使用鼠标事件的clientX和clientY属性。clientX和clientY表示鼠标当前的X坐标和Y坐标。 示例一:在鼠标点击事件中获取光标位置 document.addEvent…

    JavaScript 2023年6月10日
    00
合作推广
合作推广
分享本页
返回顶部