详解JavaScript原型与原型链

yizhihongxing

详解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日

相关文章

  • js编码、解码函数介绍及其使用示例

    js编码、解码函数介绍及其使用示例 在Web开发中,我们常常需要将数据进行编码或解码。比如将URL中的中文字符进行编码,或者将Base64编码后的数据进行解码成普通的数据等。下面介绍JS中的编码、解码函数及其使用示例。 URI编码、解码函数 URI编码使用encodeURIComponent()函数,该函数将字符串中的中文字符、特殊字符以及保留字符进行编码,…

    JavaScript 2023年5月20日
    00
  • JavaScript基础之this和箭头函数详析

    JavaScript基础之this和箭头函数详析 本文主要介绍JavaScript中的this关键字和箭头函数的使用方法和注意事项。 什么是this 在JavaScript中,this关键字代表当前执行上下文的对象。它的值是在函数执行时确定的,具体取决于函数的调用方式。 全局作用域下的this 在全局作用域下,this指向的是全局对象window。 cons…

    JavaScript 2023年6月11日
    00
  • 你不知道的 IDEA Debug调试小技巧(小结)

    我将按照标准的Markdown格式,为您详细讲解一下“你不知道的 IDEA Debug调试小技巧(小结)”,其中将包含两条示例说明。 简述 在开发过程中,调试过程是非常重要的一环。IDEA作为一款工业级别的Java开发工具,其调试功能也相当强大且易用。下面将为大家介绍一些不为人知的IDEA Debug调试小技巧,希望对大家的开发工作有所帮助。 小技巧 1. …

    JavaScript 2023年5月28日
    00
  • 利用Math.js解决JS计算小数精度丢失问题

    利用Math.js解决JS计算小数精度丢失问题的完整攻略 问题描述 在JavaScript中进行小数运算时,会容易出现精度丢失的问题,例如在进行两个小数相加时,结果并不是预期的精确值,而是一个近似值。 例如: console.log(0.1 + 0.2); // 0.30000000000000004 解决方案 解决小数精度丢失问题的最简单方法是使用第三方库…

    JavaScript 2023年5月28日
    00
  • Firefox和IE兼容性问题及解决方法总结

    Firefox和IE兼容性问题及解决方法总结 1. 兼容性问题概述 随着Web的发展,人们越来越注重Web应用的跨平台和兼容性。然而,在不同的浏览器中,同一个网站可能会出现不同的排版和功能异常等问题。特别是在Firefox和IE中兼容性问题更加明显,主要表现在以下方面: CSS兼容性问题:包括盒模型、浮动、定位等 JavaScript语法差异:例如事件绑定、…

    JavaScript 2023年6月10日
    00
  • eval有时候也可以用,而且有奇效

    eval,一个我曾经避之不及的函数,最近我对它产生了一点新的感触:eval有时候也可以用,有奇效。 一般在使用js进行开发时,是不建议使用eval这类函数的。在JavaScript中,eval可以计算传入的字符串,将其当作js代码来执行。因为它可执行js代码的特性,有可能被第三方利用,传入恶意js代码执行,因此这个函数存在安全风险。再加上eval执行的速度低…

    JavaScript 2023年4月18日
    00
  • ASP.NET搭配Ajax实现搜索提示功能

    ASP.NET是一种用于构建动态网站和Web应用程序的框架。它可以与AJAX(异步JavaScript和XML)结合使用来实现各种功能,其中之一是搜索提示功能。 搜索提示功能允许用户输入关键字时,动态地显示相关联的结果。这种实时反馈可以提高用户的操作效率和用户体验。 以下是使用ASP.NET和AJAX实现搜索提示功能的完整攻略: 创建ASP.NET Web应…

    JavaScript 2023年6月11日
    00
  • 深入解析JavaScript中函数的Currying柯里化

    深入解析JavaScript中函数的Currying柯里化 什么是Currying柯里化 Currying柯里化是一种将接收多个参数的函数转变为接收一个单一参数(最初函数的第一个参数)并且返回接收余下参数并返回结果的新函数的技术。 这种技术被称为“柯里化”,要归功于Haskell Curry,这位对逻辑学及其应用的研究尤为显著的人物。可以借助柯里化,编写出具…

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