《无所不能的JavaScript · prototype 原型链》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 近期刚转战 CSDN,会严格把控文章质量,绝不滥竽充数,欢迎多多交流。👍

文章目录


写在前面的话

又回到前端系列了,之前写后端和其他内容去了,进度落下,赶紧补一下。
本篇文章介绍一下 JavaScript 里面的一些经典知识点,先以prototype原型链开篇。
让我们开始!


快速了解

【概念说明】
JavaScript中,每个对象都有一个原型prototype属性,它指向另一个对象。这个被指向的对象也有自己的原型,以此类推,最终形成了一个原型链。原型链的顶端是Object.prototype,它是所有对象的根原型。
当我们访问一个对象的属性时,如果该对象自身没有这个属性,JavaScript会沿着原型链向上查找,直到找到匹配的属性或者到达原型链的末端。

【用代码说话】
直接上一段示例代码:

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

Person.prototype.sayHello = function() {
	console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};

const alice = new Person('Alice', 20);
alice.sayHello();  // 输出:Hello, my name is Alice and I am 20 years old.

浏览器运行该代码,F12控制台查看alice对象,如下图所示:
image.png
分析一下上图的这些内容:

  • alice 对象包含 age 和 name 两个属性和一个原型对象
  • 原型对象可以通过 alice.proto 访问,或 Person.prototype,两者是相等的
  • 原型对象的再上一次层指向 Object.prototype,再往上一层就是 null
  • 对,没有错,你看到了一个类似链式调用的东西,这是原型链

image.png

Tips:学习前端,特别是JavaScript,直接运行Demo,F12查看效果是一个快速学习方式。


知识介绍

prototype 与原型链

在 JavaScript 中,prototype 是用于实现继承和共享属性与方法的一种机制。每一个 JavaScript 对象(除了 null)在创建时都与另一个对象(称为其 “prototype”)相关联。这个 “prototype” 对象本身也有一个 “prototype”,这样一直到一个对象的 prototype 为 null 为止,这形成了一个链条,被称为 “原型链”(prototype chain)。


关于 prototype 继承

所有的 JavaScript 对象都会从一个 prototype(原型对象)中继承属性和方法:
Date 对象从 Date.prototype 继承。
Array 对象从 Array.prototype 继承。
Person 对象从 Person.prototype 继承。
所有 JavaScript 中的对象都是位于原型链顶端的 Object 的实例。
JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。
Date 对象、Array 对象、以及 Person 对象从 Object.prototype 继承。

console.log(alice.__proto__ === Person.prototype);  // 输出:true
console.log(Person.prototype.__proto__ === Object.prototype);  // 输出:true
console.log(Object.prototype.__proto__ === null);  // 输出:true

使用 prototype 添加属性

JavaScript 对象要添加新的属性或方法,很简单。
有点像 Java 的Map那边随意,直接追加即可,类似 alice.xxx = ‘1111’
但如果想追加的属性是和其他对象,继承和共享的,那就可以用到 prototype 方式。

Person.prototype.nationality = "English";
console.log(alice.__proto__.nationality);

使用 prototype 属性就可以给对象的构造函数添加新的属性和方法。


关键词 constructor
前面示例一定看到了原型对象上有一个 constructor 属性,这是何物?
其实就是和 Java 中的构造函数类似的概念,用下面代码可以看出来,原型的 constructor就是指向类本身。

alice.__proto__.constructor === Person  // true

结合前面说的内容, 整个概念是否绕来绕去,找了下面这张图,感觉能比较直观了看明白之间的调用关系。
image.png

几个概念复述一下:

  • prototype 是 JavaScript 中实现继承和共享属性与方法的基础。
  • 构造函数的 prototype 属性用于定义所有实例共享的方法和属性。
  • 每个对象都有一个 proto 属性,对象通过该属性引用其原型,形成原型链。
  • 每个函数在定义时会自动获得一个 prototype 属性,这个属性是一个对象,包含一个 constructor 属性指向函数本身。
  • 当访问对象的一个属性或方法时,JavaScript 会首先在对象本身查找。如果没有找到,它会沿着原型链向上查找,直到找到或到达链的末端(即 null)。

Tips:理解 prototype 和原型链是掌握 JavaScript 面向对象编程的关键。通过这种机制,可以实现代码的重用和更高效的内存使用。


原型链的性能和优化

原型链在JavaScript中的运作会带来一定的性能开销。在访问属性时,查找过程需要沿着原型链逐级查找,直到找到属性或者到达原型链末端。因此,过深的原型链结构可能导致性能下降。为了优化性能,可以合理设计对象的原型链,避免过于庞大和复杂的结构。

Tips:简单来说,就是不要太复杂,但一般前端设计也不应该很重,最多父子类的结构了,损耗可以忽略不计。


Java 和 JavaScript 面向对象

JavaScript 和 Java 都是面向对象编程语言,但它们在类和对象的实现和使用上有一些显著的差异。以下是对 JavaScript 中类和对象的介绍,并通过 Java 的概念进行对比说明。
类:
JavaScript ES6 引入类,使得类定义更加简洁和直观,但其底层依然基于原型链。
Java 中类是核心概念,定义了对象的属性和行为。
对象:
JavaScript 对象是键值对的集合,可以动态修改。
Java 对象是类的实例,属性和方法在类中定义。
继承:
JavaScript 通过 extends 关键字实现类的继承,使用 super 调用父类的构造函数和方法。
Java 通过 extends 关键字实现类的继承,使用 super 关键字调用父类的构造函数和方法。
总结:
尽管 JavaScript 和 Java 在语法和特性上有很多不同,但它们都支持面向对象编程的基本概念,如类、对象和继承。JavaScript 的类和对象模型更加灵活和动态,而 Java 的类和对象模型更为静态和严格。


用法拓展

创建对象的N种方式

对于 Java 后端程序猿而言,类与对象不是 Java 面向对象的概念吗,前端怎么也有?
其实 JavaScript 已经不是后端眼中随意简单的脚本语言了,Java 有的概念它也有,Java 能做的很多事情,它也能做。
我们有多种方式可以创建对象,根据不同的创建方式,JavaScript对象的原型链也会有所不同。

构造函数方式
使用构造函数方式创建对象的原型是构造函数的原型对象(prototype)。
这个前面章节都在介绍这种方式,示例代码再贴一下?

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

Person.prototype.sayHello = function() {
	console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};

const alice = new Person('Alice', 20);
alice.sayHello();  // 输出:Hello, my name is Alice and I am 20 years old.

console.log(alice.__proto__ === Person.prototype);  // 输出:true

字面量方式创建对象
使用字面量方式创建对象的原型是 Object.prototype,即所有字面量创建的对象都是 Object 的实例。

const lwObj = {
	name: '战神',
	age: 32,
	sayHello() {
		console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
	}
};

console.log(lwObj.__proto__ === Object.prototype);// 输出:true

Class 方式创建对象
在 ES6 之前,JavaScript 没有类的概念,开发者主要通过构造函数和原型链来实现面向对象编程。ES6 引入了类的语法,使得定义和继承类更加直观和类似于其他面向对象语言(如 Java)。
Class 方式创建的对象和构造函数方式创建的对象一样,其原型是Class构造函数的prototype属性所指向的对象。

Tips:这也是推荐方式,不过一般复杂的前端逻辑才会去专门设计和定义类。

class PersonClass {
	constructor(name, age) {
		this.name = name;
		this.age = age;
	}
	sayHello() {
		console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
	}
}

const hanMei = new PersonClass('HanMei', 25);
hanMei.sayHello();  // 输出:Hello, my name is HanMei and I am 25 years old.	

console.log(hanMei.__proto__ === PersonClass.prototype);  // 输出:true

prototype 实现继承

直接看下面的代码,就是基于原型链的特性。

// 定义父类函数
function Company(){  
    this.boss = 'lw';  
	  this.name = 'cjwmy';  
    this.show = function(){  
        return this.boss + ',' + this.name;  
    }  
}  

// 定义子类函数
function Zysoft(){  
    this.soft = ['zyhip','zycomm'];  
}  

// 绑定原型链
Zysoft.prototype = new Company();  
let one = new Zysoft();  
console.log(one.show());  //lw,cjwmy

扩展原有对象的方法 Demo

首先,我们要先了解一下类的概念,JavaScript 本身是一种面向对象的语言,它所涉及的元素根据其属性的不同都依附于某一个特定的类。我们所常见的类包括:数组变量(Array)、逻辑变量(Boolean)、日期变量(Date)、结构变量(Function)、数值变量(Number)、对象变量(Object)、字符串变量(String) 等,而相关的类的方法,也是程序员经常用到的(在这里要区分一下类的注意和属性发方法),例如数组的push方法、日期的get系列方法、字符串的split方法等等,但是在实际的编程过程中不知道有没有感觉到现有方法的不足?prototype 方法应运而生!

【最简单的例子,自己写add等方法,了解 prototype】
是不是很简单?这一节仅仅是告诉读者又这么一种方法,这种方法是这样运用的。

(1) Number.add(num):作用,数字相加
实现方法:Number.prototype.add = function(num){return(this+num);}
试验:alert((3).add(15)) -> 显示 18

(2) Boolean.rev(): 作用,布尔变量取反
实现方法:Boolean.prototype.rev = function(){return(!this);}
试验:alert((true).rev()) -> 显示 false

(3)测试demo
String.prototype.test = function(value) {
    alert(1)
};

【已有方法的实现和增强,初识 prototype】

(1) Array.push(new_element)
//作用:在数组末尾加入一个新的元素
Array.prototype.push = function(new_element){
    this[this.length]=new_element;
    return this.length;
}
//让我们进一步来增强他,让他可以一次增加多个元素!
Array.prototype.pushPro = function() {
    var currentLength = this.length;
    for (var i = 0; i < arguments.length; i++) {
        this[currentLength + i] = arguments[i];
    }
    return this.length;
}2)String.length
//作用:这实际上是 String 类的一个属性,但是由于 JavaScript 将全角、半角均视为是一个字符,
//在一些实际运用中可能会造成一定的问题,现在我们通过 prototype 来弥补这部不足。
String.prototype.cnLength = function(){
    var arr=this.match(/[^\x00-\xff]/ig);
    return this.length+(arr==null?0:arr.length);
}
alert("EaseWe空间Spaces".cnLength()) -> 显示 16

【新功能的实现,深入 prototype】
在实际编程中所用到的肯定不只是已有方法的增强,更多的实行的功能的要求。

(1) String.left()
//问题:用过 vb 的应该都知道left函数,从字符串左边取 n 个字符,但是不足是将全角、半角均视为是一个字符,造成在中英文混排的版面中不能截取等长的字符串
//作用:从字符串左边截取 n 个字符,并支持全角半角字符的区分
String.prototype.left = function(num,mode){
    if(!/\d+/.test(num))return(this);
    var str = this.substr(0,num);
    if(!mode) return str;
    var n = str.Tlength() - str.length;
    num = num - parseInt(n/2);
    return this.substr(0,num);
}
alert("EaseWe空间Spaces".left(8)) -> 显示 EaseWe空间
alert("EaseWe空间Spaces".left(8,true)) -> 显示 EaseWe空
//本方法用到了上面所提到的String.Tlength()方法,自定义方法之间也能组合出一些不错的新方法呀!

(2) Date.DayDiff()
作用:计算出两个日期型变量的间隔时间(年、月、日、周)
Date.prototype.DayDiff = function(cDate,mode){
       try{
           cDate.getYear();
       }catch(e){
           return(0);
       }
       var base =60*60*24*1000;
       var result = Math.abs(this - cDate);
       switch(mode){
           case "y":
               result/=base*365;
               break;
           case "m":
               result/=base*365/12;
               break;
           case "w":
               result/=base*7;
               break;
           default:
               result/=base;
               break;
       }
       return(Math.floor(result));
   }
alert((new Date()).DayDiff((new Date(2002,0,1)))) -> 显示 329
alert((new Date()).DayDiff((new Date(2002,0,1)),"m")) -> 显示 10
//当然,也可以进一步扩充,得出响应的小时、分钟,甚至是秒。

(3) Number.fact()
//作用:某一数字的阶乘
Number.prototype.fact=function(){
   var num = Math.floor(this);
   if(num<0)return NaN;
   if(num==0 || num==1)
       return 1;
   else
       return (num*(num-1).fact());
}
alert((4).fact()) -> 显示 24
//这个方法主要是说明了递归的方法在 prototype 方法中也是可行的!

(4) Array.indexof()
//下面是给js中的Array加的一个方法(本来js中Array是没有返回下标的方法的)
Array.prototype.indexof = function(value) {
    var a = this;
    for (var i = 0; i < a.length; i++) {
        if (a[i] == value)
            return i;
    }
}
var arr = ['1', '2', '3', '4', '5', '6', '7'];
alert(arr.indexof('3'));

prototype 基础测试 Demo

本章节,是博主早期针对 prototype 做的一些测试代码,可以跳过。

===== 第一例,prototype初使用--为类型增加额外的方法和属性  
Object.prototype.Property = 1;
Object.prototype.Method = function (){ 
    alert(1);
}
var obj = new Object();
alert(obj.Property);
obj.Method();
结论:可以在类型上使用proptotype来为类型添加行为,这些行为只能在类型的实例上体现,并且在增加之前实例化的对象也享有这些变化。
规则1:JS中允许的内置类型有Array, Boolean, Date, Enumerator, Error, Function, Number, Object, RegExp, String;
规则2:直接用Object.Method()也可以调用(但一般不这么使用),因为Object是所有对象(包括函数对象)的基础,其他内置类型是不可以。

===== 第二例,在实例对象上不能使用prototype,否则发生编译错误 
var obj = new Object();
obj.prototype.Property = 1; //Error
obj.prototype.Method = function() //Error
{
    alert(1);
}

===== 第三例,直接给类型定义"静态"属性和方法,只能使用类型本身调用,对象无法调用,同Java的static关键字声明的类变量
Object.Property = 1;
Object.Method = function()
{
    alert(1);
}
alert(Object.Property);
Object.Method();    //正常调用
var obj = new Object();
alert(obj.Property);  //Error实例不能调用类型的静态属性或方法,否则发生对象未定义的错误。

===== 第四例,演示通常在JavaScript中定义一个自定义类型的方法
function Aclass()
{
this.Property = 1;
this.Method = function()
{
    alert(1);
}
}
var obj = new Aclass();
alert(obj.Property);
obj.Method();

===== 第五例,接第四例,可以在外部使用prototype为自定义的类型添加属性和方法。
Aclass.prototype.Property2 = 2;
Aclass.prototype.Method2 = function
{
    alert(2);
}
var obj = new Aclass();
alert(obj.Property2);
obj.Method2();

===== 第六例,接第四例,在外部不能通过prototype改变自定义类型的属性或方法,不会报错但改变无效;
但如果属性本身就是通过prototype扩展的,则可以继续用prototype修改。
Aclass.prototype.Property = 2;
Aclass.prototype.Method = function
{
    alert(2);
}
var obj = new Aclass();
alert(obj.Property); //仍然弹出1
obj.Method();

===== 第七例,接第四例,可以在对象上改变属性。(这个是肯定的)
var obj = new Aclass();
obj.Property = 2;
obj.Method = function()
{
    alert(2);
}
alert(obj.Property);
obj.Method();
也可以在对象上改变方法。(和普遍的面向对象的概念不同)

===== 第八例,接第四例,可以在对象上增加属性或方法   
var obj = new Aclass();
obj.Property2 = 2;
obj.Method2 = function()
{
    alert(2);
}
alert(obj.Property2);
obj.Method2();

===== 第九例,接第四例,这个例子说明了一个类型如何从另一个类型继承。  
function AClass2()
{
       this.Property2 = 2;
       this.Method2 = function()
       {
              alert(2);
       }
}
AClass2.prototype = new AClass();
 
var obj = new AClass2();
alert(obj.Property);
obj.Method();
alert(obj.Property2);
obj.Method2();

===== 第十例,接上例, 这个例子说明了子类如何重写父类的属性或方法。但不能改变自身的属性和方法。
AClass2.prototype = new AClass();()
AClass2.prototype.Property = 3;
AClass2.prototype.Method = function()
{
       alert(4);
}
var obj = new AClass2();
alert(obj.Property);
obj.Method();
可见JavaScript能够实现的面向对象的特征有:·公有属性(public field)·公有方法(public Method)·私有属性(private field)·私有方法(private field)·方法重载(method overload)·构造函数(constructor)·事件(event)·单一继承(single inherit)·子类重写父类的属性或方法(override)·静态属性或方法(static member)

总结陈词

本篇文章分享一下 JS 世界中prototype的用法,希望能帮助到大家。
后端程序猿如果想往全栈工程狮发展,那JavaScript必须和Java玩得一样明白,接下来系列文章,带你一起探索,无所不能的JavaScript
💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。

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

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

相关文章

python集成Bartender实现二维码打印

本文摘录于&#xff1a;https://blog.csdn.net/mynameisJW/article/details/105500773只是做学习备份之用&#xff0c;绝无抄袭之意&#xff0c;有疑惑请联系本人&#xff01; 这里上传我优化了一下的代码:https://download.csdn.net/download/chengdong1314/89522026 我这里弄…

Web3时代的数字身份认证:安全性与隐私保护探讨

随着区块链技术的发展和普及&#xff0c;数字身份认证正逐步成为Web3时代的关键基础设施。传统的身份认证系统存在着中心化数据存储、数据泄露和身份盗用等风险&#xff0c;而基于区块链的数字身份认证则通过去中心化、加密和分布式存储等特性&#xff0c;重新定义了安全性和隐…

Alpha 3D扫描仪

3D视觉。就这么简单。 用于机器视觉任务的工业3D扫仪 规格表

Nginx理论篇与相关网络协议

Nginx是什么&#xff1f; Nginx是一款由C语言编写的高性能、轻量级的web服务器&#xff0c;一个线程能处理多个请求&#xff0c;支持万级并发。 优势&#xff1a;I/O多路复用。 I/O是什么&#xff1f; I指的是输入&#xff08;Input&#xff09;,O是指输出&#xff08;Outp…

springboot事故车辆与违章车辆跟踪系统-计算机毕业设计源码03863

springboot事故车辆与违章车辆跟踪系统 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。…

品牌故事的智能叙述者:Kompas.ai如何塑造品牌叙事

在品牌的世界里&#xff0c;故事是连接消费者与品牌灵魂的桥梁。一个引人入胜的品牌故事不仅能够建立品牌身份&#xff0c;还能够在消费者心中建立起深厚的情感联系。Kompas.ai&#xff0c;作为一款利用人工智能技术的品牌叙事工具&#xff0c;正在帮助品牌创造和传播引人入胜的…

WMS海外仓系统应用:如何改善海外仓的12个核心业务流程

现代化跨境电商的发展依赖海外仓的高效运转&#xff0c;从货物入仓到订单拣货再到最后的货物出库&#xff0c;全部流程都需要海外仓可以顺畅应对。 作为海外仓&#xff0c;则需要借助诸如WMS海外仓系统这样的智能化管理方式&#xff0c;才能适应日益复杂的客户需求。今天我们就…

案列:Nginx+Tomcat负载均衡、动静分离群集

一、案列&#xff1a;部署Tomcat&#xff08;在192.168.10.102和192.168.10.103&#xff09; 1.关闭防火墙 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2.安装java环境 [rootlocalhost ~]# yum -y install java [rootlocalhost ~]# jav…

724.力扣每日一题7/8 Java

博客主页&#xff1a;音符犹如代码系列专栏&#xff1a;算法练习关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 目录 思路 解题方法 时间复杂度 空间复杂度 Code 思路 主要基于数组的…

Git 详解(原理、使用)

1. 什么是 Git Git 是目前最主流的一个版本控制器&#xff0c;并且是分布式版本控制系统&#xff0c;可以控制电脑上所有格式的文档 版本控制器&#xff1a;记录每次修改以及版本迭代的管理系统 对于文本文件&#xff0c;可以记录每次对这个文件的内容进行了怎样的修改 对于二…

视频汇聚平台EasyCVR设备录像回看请求播放时间和实际时间对不上,是何原因?

安防监控EasyCVR视频汇聚平台可提供多协议&#xff08;RTSP/RTMP/国标GB28181/GAT1400/海康Ehome/大华/海康/宇视等SDK&#xff09;的设备接入、音视频采集、视频转码、处理、分发等服务&#xff0c;系统具备实时监控、云端录像、回看、告警、平台级联以及多视频流格式分发等视…

【Python】已解决:(最新版selenium框架元素定位报错)NameError: name ‘By’ is not defined

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;&#xff08;最新版selenium框架元素定位报错&#xff09;NameError: name ‘By’ is not defined 一、分析问题背景 在使用Selenium进行Web自动化测试或爬虫开…

使用MySQLInstaller配置MySQL

操作步骤 1.配置High Availability 默认选项Standalone MySQL Server classic MySQL Replication 2.配置Type and Networking ◆端口默认启用TCP/P网络 ◆端口默认为3306 3.配置Account and Roles 设置root账户的密码、添加其他管理员 4.配置Windows Service ◆配置MySQL Serv…

Redis连接Resp图形化工具和springboot

Redis连接Resp图形化工具和springboot 1.redis配置1.1 备份、修改conf文件1.2 Redis的其它常见配置&#xff1a;1.3 启动Redis&#xff1a;1.4 停止服务&#xff1a;1.5 开机自启&#xff1a; 2. resp的安装、配置和连接&#xff1a;2.1 GitHub上下载2.2 开始连接redis ![在这里…

服务器数据恢复—raid5阵列热备盘没有激活导致阵列崩溃的数据恢复案例

服务器存储数据恢复环境&#xff1a; 一台EMC存储中有一组raid5磁盘阵列&#xff0c;划分1个lun供小型机使用&#xff0c;上层采用ZFS文件系统。 服务器存储故障&#xff1a; 一台有一组raid5磁盘阵列的存储在运行过程中突然崩溃。管理员检查发现存储中的raid5阵列有两块硬盘离…

【Linux进阶】vim的用法

1.什么是vi/vim? 简单来说&#xff0c;vi是老式的文本编辑器&#xff0c;不过功能已经很齐全了&#xff0c;但是还是有可以进步的地方。vim则可以说是程序开发者的一项很好用的工具&#xff0c;就连 vim的官方网站&#xff08; http://www.vim.org&#xff09;自己也说vim是一…

【知网CNKI-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

使用PyTorch设计卷积神经网络(CNN)来处理遥感图像Indian Pines数据集

目录 使用PyTorch设计卷积神经网络&#xff08;CNN&#xff09;来处理遥感图像Indian Pines数据集&#xff0c;以下是设计和实现这些网络的步骤&#xff1a; 1.数据准备&#xff1a; 1.1 首先&#xff0c;需要加载Indian Pines数据集。 1.2 将数据集转换为PyTorch张量&#x…

股指期货有哪些对冲类型?

股指期货对冲交易主要分为两类&#xff1a;沽出&#xff08;卖出&#xff09;对冲和揸入&#xff08;购入&#xff09;对冲。 沽出对冲旨在保护未来股票组合价格下跌的风险。在此策略下&#xff0c;对冲者通过出售期货合约来锁定未来的现金售价&#xff0c;并将价格风险从股票…

软件架构之计算机网络

软件架构之计算机网络 第 4 章 计算机网络4.1 网络架构与协议4.1.1 网络互联模型4.1.2 常见的网络协议4.1.3 IPv6 4.2 局域网与广域网4.2.2 无线局域网4.2.3 广域网技术4.2.4 网络接入技术 4.3 网络互连与常用设备4.4 网络工程4.4.1 网络规划4.4.2 网络设计4.4.3 网络实施 4.5 …