js 原型对象和原型链理解

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实现自定义事件的完整攻略如下: 1. 什么是自定义事件 在JavaScript中,事件驱动编程是非常常见的。传统的事件模型包含了标准事件(如:click、focus等),当这些事件发生时会触发相应的处理函数。除了标准事件外,还存在一种类型的事件,即自定义事件。自定义事件是由开发者定义的事件,可以手动派发和监听。自定义事件的应用场景非常…

    JavaScript 2023年6月10日
    00
  • 网站程序中非SI漏洞的利用

    非SI漏洞指的是与系统集成无关的漏洞,这些漏洞通常存在于特定的网站程序中,可以被攻击者利用来访问受保护的文件、执行命令或者绕过身份验证等。以下是针对网站程序中非SI漏洞的利用的完整攻略。 准备工作 在开始攻击之前,需要进行以下准备工作: 确认目标网站程序的版本信息。 收集目标网站程序的相关信息,包括文件路径、参数名称、请求方式等。 准备必要的工具和软件,如B…

    JavaScript 2023年6月10日
    00
  • JS中创建函数的三种方式及区别

    下面为您详细讲解JS中创建函数的三种方式及区别的完整攻略。 一、函数定义方式 函数定义是最常见的创建函数的方式,语法如下: function functionName(param1, param2, …) { // 函数体 return value; } 该方式创建的函数可以被整个作用域访问到,包括其内部的变量和函数。下面是一个示例: function …

    JavaScript 2023年5月27日
    00
  • javascript与cookie 的问题详解

    JavaScript与Cookie的问题详解 在这篇攻略中,我将分享一些关于 JavaScript 和 Cookie 的基础知识,解释它们之间的关系以及一些常见的问题。 什么是JavaScript? JavaScript 是一门编程语言,通常用于为网页添加交互性和动态效果。与 HTML 和 CSS 不同,JavaScript 可以让网页与用户交互并响应用户的…

    JavaScript 2023年6月11日
    00
  • JavaScript块级作用域绑定的实现流程

    JavaScript的块级作用域绑定是ES6中新增的特性,它使得变量声明可以仅在块级作用域中起作用,可以避免因变量定义不当所出现的一些各种问题。块级作用域是指一对花括号”{ }”之间的区域,这种变量称为块级作用域变量。 实现块级作用域绑定的流程主要依靠let和const关键字这两个特性。let关键字声明的变量只在声明位置所在的块级作用域内有效,const关键…

    JavaScript 2023年5月27日
    00
  • JavaScript必知必会(九)function 说起 闭包问题

    下面是我对“JavaScript必知必会(九)function 说起 闭包问题”的完整攻略。 什么是闭包 闭包是指函数和函数所能访问的外部变量之间的关系。可以理解为,一个函数能够“记住”在它被定义时所处的环境。 一个闭包的形成,需要满足以下条件: 函数嵌套:在一个函数内定义了另一个函数。 内层函数使用了外部变量:内层函数使用了外部函数所定义的变量。 外部函数…

    JavaScript 2023年6月10日
    00
  • 一文带你理解JavaScript中的函数式编程

    “一文带你理解JavaScript中的函数式编程”的完整攻略 什么是函数式编程? 函数式编程是一种编程范式,它将计算机程序看作一系列数学函数的组合,避免使用共享状态和可变数据,通过数据不可变和函数无副作用的特性实现函数的组合和复用。JavaScript原生支持函数式编程,在近年来的JavaScript开发中也越来越普遍。 函数式编程的特点 函数是一等公民:函…

    JavaScript 2023年5月27日
    00
  • Vue-Router进阶之滚动行为详解

    Vue-Router进阶之滚动行为详解 什么是滚动行为?为什么需要滚动行为? 在Vue-Router中,我们可以使用路由跳转来实现前后端页面之间的跳转,但是当我们来回切换不同的路由时会发现一个问题:每次切换完页面,新页面都会从顶部开始显示,这给用户带来了不好的体验。 这个问题可以通过设置滚动行为来解决。滚动行为可以定义在路由配置中,配合自定义行为函数,实现路…

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