js 原型对象和原型链理解

yizhihongxing

JS 原型对象和原型链理解

在 JavaScript 中,每个对象都有一个内部属性 [[Prototype]],也可以叫做原型,它指向另一个对象,而后者则有自己的原型,这样就形成了一个链接的原型链。最终的原型指向 null

原型对象

原型对象是函数对象的一个属性 prototype,它是一个对象,包含了一些属性和方法,这些属性和方法会被实例对象所继承。每当定义一个新函数时,都会自动生成一个包含 constructor 属性和其他默认属性的对象,这个对象就是函数的原型。

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

Person.prototype.sayName = function() {
  console.log(this.name);
};

let person = new Person('Tom', 18);
console.log(person.__proto__ === Person.prototype);  // true
console.log(person.constructor === Person);  // true

在上面的例子中,Person.prototype 对象上定义了一个 sayName 方法,这个方法会被 person 对象所继承。

原型链

每个对象都有一个内部属性 [[Prototype]],它指向另一个对象,另一个对象也有它自己的 [[Prototype]],这样就形成了一个链接的原型链。当我们访问一个对象的某个属性或方法时,首先会在自身属性和方法中查找,如果没有找到,就会沿着原型链一级一级向上查找,直到找到为止,如果一直到最顶层都没有找到,就会返回 undefined

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

Person.prototype.sayName = function() {
  console.log(this.name);
};

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

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

let student = new Student('Tom', 18, '三年级');
console.log(student.__proto__ === Student.prototype);  // true
console.log(student.__proto__.__proto__ === Person.prototype);  // true
console.log(student.__proto__.__proto__.__proto__ === Object.prototype);  // true
console.log(student.__proto__.__proto__.__proto__.__proto__);  // null

在上面的例子中,Student.prototype 继承了 Person.prototype,而 Person.prototype 则继承了 Object.prototype,最终的原型链就是 student.__proto__ -> Student.prototype -> Person.prototype -> Object.prototype -> null

总结

JavaScript 通过原型链实现继承,每个对象都有一个 [[Prototype]] 属性,它指向另一个对象,这样就形成了一个链接的原型链。原型链上的属性和方法会被对象继承,当我们访问一个对象的某个属性或方法时,会沿着原型链一级一级向上查找。

需要注意的是,虽然我们可以通过直接修改 __proto__ 属性或 Object.setPrototypeOf() 方法来修改对象的原型,但是这种行为并不推荐,它会导致 JavaScript 引擎进行一些非常耗费性能的优化和检查工作。建议我们使用 Object.create() 方法和构造函数来进行继承和原型对象的维护,以保证代码的可读性和可维护性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:js 原型对象和原型链理解 - Python技术站

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

相关文章

  • JavaScript中关于数组的调用方式

    JavaScript中的数组是一组值的有序集合,可以通过数字索引来访问这些值。在JavaScript中,数组可以通过几种不同的方式来创建和访问。 创建数组 JavaScript中的数组可以通过以下两种方式来创建: 直接使用方括号[]来创建一个空数组,如下所示: const arr1 = []; 使用方括号[]并在其中包含数组元素,如下所示: const ar…

    JavaScript 2023年5月27日
    00
  • js 数组 find,some,filter,reduce区别详解

    当我们在开发 JavaScript 程序时,经常会用到数组的各种方法,其中包括 find、some、filter 和 reduce 等方法。这些方法可以帮助我们在数组中找到特定的元素、过滤不需要的元素、对数组进行操作并返回新的数组等。 下面就一个一个地详细讲解这些方法的用法和区别: find 方法 find 方法返回满足条件的第一个元素,如果找不到,返回 u…

    JavaScript 2023年5月27日
    00
  • js编写trim()函数及正则表达式的运用

    让我来详细讲解一下如何写js中的trim()函数以及正则表达式的运用。 编写js中的trim()函数 在js中,字符串的trim()函数可以去除字符串两端的空格,但是在一些老版本的浏览器中可能不支持。因此我们可以自己编写一个trim()函数来解决这个问题。 方法一:使用正则表达式 通过正则表达式,我们可以去掉字符串两端的空格。具体实现代码如下: functi…

    JavaScript 2023年6月10日
    00
  • JavaScript 面向对象之命名空间

    JavaScript 面向对象之命名空间 JavaScript 是一门支持面向对象编程的语言,但在实践中,我们发现 JavaScript 的命名空间机制并不完整或者说不够严谨。因此,我们可以借助 Object 对象和函数声明的方式来实现 JavaScript 的命名空间。 命名空间的概念 命名空间是一个用于“组织代码”的容器,它类似于文件系统中文件夹的概念,…

    JavaScript 2023年5月27日
    00
  • 由Javascript实现的页面日历

    下面是由Javascript实现的页面日历的完整攻略: 1.准备HTML和CSS 首先,在HTML中创建一个容器用于包含整个日历,然后为日历添加CSS样式以控制其外观。以下是一个示例: <div id="calendar"></div> #calendar { width: 300px; height: 300px…

    JavaScript 2023年6月10日
    00
  • 微信小程序防止多次点击跳转和防止表单组件输入内容多次验证功能(函数防抖)

    微信小程序中,为了提高用户体验,往往需要对一些按钮或表单组件进行防止多次点击或输入内容多次验证,以避免用户重复提交数据或误操作。这时,我们可以使用函数防抖来实现这些效果。 函数防抖是指在一段时间内,多次触发同一事件,只执行一次函数。具体而言,是在延迟时间内,如果再次触发了同一事件,则清空之前的计时器并重新开始计时,直到延迟时间过去后再触发该事件时才会执行真正…

    JavaScript 2023年6月10日
    00
  • JavaScript正则表达式解析URL的技巧

    JavaScript正则表达式可以用于解析URL,可以通过正则表达式对URL进行匹配和处理,具体步骤如下: 使用正则表达式匹配URL中的协议、域名、路径、查询参数等各个部分; 将匹配结果包装成对象,方便后续的解析和处理; 通过对象的属性和方法对URL进行分析和操作。 下面分别对这三个步骤进行详细讲解。 1.使用正则表达式匹配URL的各个部分 正则表达式可以很…

    JavaScript 2023年6月10日
    00
  • js时间转换毫秒的实例代码

    JS时间转换毫秒是一个常用的功能,在前端开发中经常需要对时间进行计算,因此,掌握JS时间转换毫秒的方法是必要的。 1. Date对象的getTime()方法 在JS中,Date对象提供了一个叫做getTime()的方法,可以将日期对象转换成自1970年1月1日 00:00:00 UTC(协调世界时)以来的毫秒数。示例代码如下: var date = new …

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