js原型和类---prototype,__proto__,new,class

原型和原型链

在js中,所有的变量都有原型,原型也可以有原型原型最终都指向Object

什么是原型

在js中,一个变量被创建出来,它就会被绑定一个原型;比如说,任何一个变量都可以使用console.log打印,这里是调用了它的toString方法,而变量被创建后可能并没有设置toString方法,但是它任然可以打印,这就从原型中获取的toString方法

 所以可以得到第一点:原型可以提供方法给实例的变量,

原型也是一个对象,或者说对象可以作为原型并赋值给其他变量,这样对象成为了变量的原型,而对象本身也有原型,此时就形成了 ‘链’

同样的这个变量也是一个对象,他也可以作为其他变量的原型,这样‘链’就变得更长了,但是所有的链都有一个最终指向(root终点)--- Object,Obejct是最原始的对象,它包含了所有js变量都共享的方法,它不再有原型属性[[prototype]], 所以在js中一切皆对象中的对象就是指的继承自Object

这里可以总结一下:

  • 原型是一个对象,它可以向继承了自身的变量提供方法(属性)
  • 变量都拥有原型,也可以成为原型,循环下去可以形成‘链’,
  • 链的最顶端是Object对象,它提供了最基本的方法

js通过原型来复用通用的方法和属性,这样极大的减少了变量创建的成本(减少了内存支出,原型的方法属性都存储在原型上,变量中不会复制过来占用内存;也不必每个对象都去书写基本的方法),

tips:

原型链:就前面说到的 变量获得原型,原型又有原型,变量又可以作为原型,这样就形成了‘链’,链的最外层(底层),拥有最多的方法,继承了原型链上所有原型的方法和属性

prototype

在 JavaScript 中,对象有一个特殊的隐藏属性 [[Prototype]](如规范中所命名的),它要么为 null,要么就是对另一个对象的引用。当我们从 object 中读取一个缺失的属性时,JavaScript 会自动从原型中获取该属性。这就是继承,object也可以从中借用方法

prototype不能在变量中被直接引用,通常没有办法遍历或者读取这个属性,所以它在控制台的名称有些特殊,使用[[ ]]引用,但是可以直接去调用它里面的方法,当你使用变量中不存在的属性或者方法,此时会自动向原型中寻找,对应的属性方法并调用,若原型链中没有则返回undefined

但是也有特例,在构造函数中,可以给构造的实例添加原型属性或方法

__proto__

这是一个过时的属性,现在只能在浏览器中使用,它的作用就是指向prototype,给原型添加属性或方法,这样添加的原型属性或方法会被遍历出来(Object.keys,for in),

let animal = {
  eats: true
};
let rabbit = {
  jumps: true
};

rabbit.__proto__ = animal; // 设置 rabbit.[[Prototype]] = animal

注意__proto__ 与内部的 [[Prototype]] 不一样__proto__ 是 [[Prototype]] 的getter/setter;获取和设置原型可以使用函数 Object.getPrototypeOf/Object.setPrototypeOf 来替代 __proto__ 去 get/set 原型

new

当使用 new 关键字调用函数时,该函数将被用作构造函数。new 将执行以下操作:

  1. 创建一个空的简单 JavaScript 对象作为实例。
  2. 如果构造函数的 prototype 属性是一个对象,则将实例的 原型[[Prototype]] 指向构造函数的 prototype 属性,否则实例将保持为一个普通对象,其 [[Prototype]]为 Object.prototype, 因此,通过构造函数创建的所有实例都可以访问添加到构造函数 prototype 属性中的属性/对象。
  3. 使用给定参数执行构造函数,并将this指向实例
  4. 如果构造函数返回非原始值,则该返回值成为整个 new 表达式的结果。否则,如果构造函数未返回任何值或返回了一个原始值,则返回实例。(通常构造函数不返回值,但可以选择返回值,以覆盖正常的对象创建过程。)

 new的关键点在于,它新建了一个实例对象,同时引入了原型,改变了构造函数的this指向,让实例对象成为了这个构造函数的构造结果

class

class是es6新增的语法糖,它简化了js中构造类的步骤,隐去了对原型的操作(根本上还是原型的操作),js中的类是基于原型的,使用原型达到继承的效果,

以下使用原型prototype和类class构建一个相同的类,

prototype.js

// 使用原型构造一个P类

// 构造器,大写开头规范(不强制)
function P (x,y){
  // this指向实例,此时this不生效,构造实例后指向实例
  this.x = x;
  this.y = y;
  // 实例方法,此处的this指向实例,可以使用实例的属性
  this.getXY = ()=>{
    return [this.x,this.y]
  }
}

// 实例方法,此处的this指向windows,不能使用实例的属性
P.prototype.getPName = ()=>{
  return P.name
}

// 实例属性
P.prototype.desc = '2维坐标'

//类方法/静态方法 
P.getP = (p1,p2)=>{
  return [p1.getXY(),p2.getXY()]
}

// 类属性/静态属性
P.des = '坐标'

class.js 

// 使用class构造一个P类

class P{
  //构造器
  constructor(x,y){
    this.x = x;
    this.y = y;
  }

  // 实例属性
  desc = '2维坐标'

  // 实例方法
  getXY(){
    return [this.x,this.y]
  }
  getPName(){
    return P.name
  }

  // 静态属性
  static des = '坐标'

  // 静态方法
  static getP(p1,p2){
    return [p1.getXY(),p2.getXY()]
  }
  
}

很明显,class的用法更加整体化,但实际上这两种的写法效果是完成相同的,

可以使用同一串代码来实例化这个类P

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>prototype,class</title>
</head>

<body>
  <script src="class.js"></script>
  <!-- <script src="prototype.js"></script> -->
  <script>
    // new关键字,新建一个对象,原型指向类,获得构造器中的this指向
    let p = new P(1, 2);
    console.log(p);
    console.log(p.x);
    console.log(p.y);
    console.log(p.desc);
    console.log(p.getXY());
    console.log(p.getPName());
    console.log(P.getP(p, p));
    console.log(P.des);
  </script>
</body>

</html>

实现的效果是一致的方法上略有不同,对于类的构造,关键在于this的指向问题,属性和方法是挂在类名下的,还是挂在实例下的需要区分开,

挂在类下的属性方法被称为,类方法(属性)或者静态方法(属性),通过类名引用(Math.max)

挂在实例下的属性方法被称为,实例方法(属性),通过实例引用(arr.push)

总结

  • 在 JavaScript 中,所有的对象都有一个隐藏的 [[Prototype]] 属性,它要么是另一个对象,要么就是 null
  • 通过 [[Prototype]] 引用的对象被称为“原型”。
  • "prototype" 属性仅当设置在一个构造函数上,并通过 new 调用时,才具有这种特殊的影响。在常规对象上,prototype 会被当成是一个普通的属性名
  • 所以变量都通过原型/原型链使用共享的方法(即自身不存在,从原型/原型链中借用)
  • 类的使用要区分实例和静态类,哪些方法属性在类名下,哪些方法属性在实例下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/789814.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

支持向量机 (support vector machine,SVM)

支持向量机 &#xff08;support vector machine&#xff0c;SVM&#xff09; flyfish 支持向量机是一种用于分类和回归的机器学习模型。在分类任务中&#xff0c;SVM试图找到一个最佳的分隔超平面&#xff0c;使得不同类别的数据点在空间中被尽可能宽的间隔分开。 超平面方…

数据采集:如何使用八爪鱼采集BOSS直聘职位数据

大家好&#xff0c;我是水哥&#xff01; 今天给大家分享的是数据采集实战&#xff1a;使用「八爪鱼」第三方工具来采集 BOSS 直聘上的数据分析职位数据。 接下来&#xff0c;我们详细看一看。 不重复造轮子 在工作中&#xff0c;我们一定要形成一个认知&#xff0c;能用第…

初次用bable遍历vue项目下的中文

利用 babel 找到 AST 中的中文 // vite-plugin-babel-transform.js const parser require(babel/parser) const traverse require(babel/traverse).default // const types require(babel/types) // const generate require(babel/generator).default const fs require(f…

.Net C#执行JavaScript脚本

文章目录 前言一、安装二、执行 JavaScript 脚本三、与脚本交互四、JS 调用 C# 方法五、多线程使用总结 前言 ClearScript 是一个 .NET 平台下的开源库&#xff0c;用于在 C# 和其他 .NET 语言中执行脚本代码。它提供了一种方便和安全的方法来将脚本与应用程序集成&#xff0c;…

使用Go编写的持续下行测速脚本,快速消耗流量且不伤硬盘

介绍 使用go语言编写的持续下行测速脚本,可用于任意平台使用,通过指定URL清单文本文件自动遍历测速,支持多线程,支持多平台 特性 轻量级,无依赖采用内存进行缓存数据,不占用磁盘(如果内存较小请使用gcd项目)&#xff0c;最大程度减少磁盘IO,保护硬盘寿命可自定义最大下载文件…

Hum Brain Mapp:青春期早期的灰质流失可以用白质生长来解释吗?

摘要 关于大脑发育的一个基本谜题是&#xff0c;为什么儿童进入青春期时&#xff0c;灰质(GM)体积明显减少&#xff0c;而白质(WM)体积明显增加。一种流行的理论认为&#xff0c;由于被修剪的突触太小而不足以影响脑灰质体积&#xff0c;因此大脑总体积保持稳定&#xff0c;而…

Puppeteer 是什么以及如何在网络抓取中使用它 | 2024 完整指南

网页抓取已经成为任何处理网页数据提取的人都必须掌握的一项重要技能。无论你是开发者、数据科学家还是希望从网站收集信息的爱好者&#xff0c;Puppeteer都是你可以使用的最强大工具之一。本完整指南将深入探讨什么是Puppeteer以及如何有效地在网页抓取中使用它。 Puppeteer简…

wifi模组Ai-M62-32S的IO映射和UDP透传测试

wifi模组Ai-M62-32S的IO映射和UDP透传测试 基本IO 映射配网示例开启UDP透传示例复位AT查询wifi是否在线配置DHCP静态IP连接wifi连接UDP开启透传 基本IO 映射 对于wifi模组Ai-62-32S来说其模组 IO 引脚&#xff08;从模组左上角逆时针排序&#xff0c;引脚序号从 1 开始&#x…

LeetCode 2 两数相加

题目 给你两个 非空 的链表&#xff0c;表示两个非负的整数 它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表 你可以假设除了数字 0 之外&#xff0c;这两个数都不会以…

小程序需要进行软件测试吗?小程序测试有哪些测试内容?

在如今移动互联网快速发展的时代&#xff0c;小程序已成为人们生活中不可或缺的一部分。然而&#xff0c;面对日益增长的小程序数量和用户需求&#xff0c;小程序的稳定性和质量问题日益突显。因此&#xff0c;对小程序进行软件测试显得尤为重要。 近期的一项调查显示&#xf…

鸿蒙语言基础类库:【@ohos.util (util工具函数)】

util工具函数 说明&#xff1a; 本模块首批接口从API version 7开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 该模块…

3d已经做好的模型怎么改单位?---模大狮模型网

在展览3D模型设计行业中&#xff0c;经常会遇到需要将已完成的模型进行单位转换的需求。这可能涉及从一种度量单位转换为另一种&#xff0c;例如从英制单位转换为公制单位&#xff0c;或者根据特定的展览场地要求进行尺寸调整。本文将探讨如何有效地修改已完成的3D模型的单位&a…

js实现图片放大镜功能,简单明了

写购物项目的时候&#xff0c;需要放大图片&#xff0c;这里用js写了一个方法&#xff0c;鼠标悬浮的时候放大当前图片 这个是class写法 <!--* Descripttion: * Author: 苍狼一啸八荒惊* LastEditTime: 2024-07-10 09:41:34* LastEditors: 夜空苍狼啸 --><!DOCTYPE …

【CSS in Depth 2 精译】2.4 视口的相对单位

当前内容所在位置 第一章 层叠、优先级与继承第二章 相对单位 2.1 相对单位的威力2.2 em 与 rem2.3 告别像素思维2.4 视口的相对单位 ✔️2.5 无单位的数值与行高2.6 自定义属性2.7 本章小结 2.4 视口的相对单位 前面介绍过的 em 和 rem 是相对于 font-size 定义的&#xff0…

【Pikachu靶场】安装部署通关详解超详细!!!(持续更新)

安装部署 Pikachu靶场&#xff0c;是一个带有漏洞的Web应用系统&#xff0c;在这里包含了常见的web安全漏洞。使用世界上最好的语言PHP进行开发-_-&#xff0c;数据库使用的是mysql&#xff0c;因此运行Pikachu你需要提前安装好"PHPMYSQL中间件&#xff08;如apache,ngin…

【HTML入门】第八课 - 链接的学习(二)

我们上一节学习了&#xff0c;链接的基本知识&#xff0c;有锚点&#xff0c;还有鼠标上移的title属性的作用&#xff0c;这一节&#xff0c;我们继续说链接的知识点。 目录 1 跳转本项目的网页 1.1 修改html文件名 1.2 新建index1.html文件 1.3 修改index1.html文件 1.4…

python7:装饰器

目录 1.调用外部程序os.system-阻塞式调用subprocess-python中的模块 2.装饰器前戏作用域&#xff08;1&#xff09;全局和局部-就近原则&#xff08;2&#xff09;嵌套作用域&#xff08;3&#xff09;内置作用域、变量 高阶函数&#xff1a;函数是最高级的对象&#xff08;1&…

几种不同的方式禁止IP访问网站(PHP、Nginx、Apache设置方法)

1、PHP禁止IP和IP段访问 <?//禁止某个IP$banned_ip array ("127.0.0.1",//"119.6.20.66","192.168.1.4");if ( in_array( getenv("REMOTE_ADDR"), $banned_ip ) ){die ("您的IP禁止访问&#xff01;");}//禁止某个IP段…

【Linux操作系统-测试】第三节.Linux 系统、网络信息、用户权限命令总结

文章目录 前言一、Linux 系统相关信息命令 1.1 df 命令--查看磁盘剩余 1.2 ps 命令--查看进程 1.3 top 命令--显示进程运行状态 1.4 kill 命令说明 -- 杀死进程二、Linux 网络信息命令 2.1 ping 命令--检查网络是否连通 2.1 ifconfig--显示网络设…

传知代码-图神经网络长对话理解(论文复现)

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 概述 情感识别是人类对话理解的关键任务。随着多模态数据的概念&#xff0c;如语言、声音和面部表情&#xff0c;任务变得更加具有挑战性。作为典型解决方案&#xff0c;利用全局和局部上下文信息来预测对话中每…