JavaScript学习笔记(三)
文章目录
- 第7章:迭代器与生成器
- 1. 迭代器模式
- 2. 生成器
- 第8章:对象、类与面向对象编程
- 1. 理解对象
- 2. 创建对象
- 3. 继承:依靠原型链实现
- 4. 类class
- 第10章:函数
- 1. 函数定义的方式有:函数声明、函数表达式、箭头函数,Function构造函数。
- 2.箭头函数(=>)
- 3. 函数名:就是指向函数的指针。
- 4. 理解参数
- 5. 没有重载
- 6. 默认参数值
- 7. 参数扩展与收集
- 8. 函数声明与函数表达式
- 9. 函数作为值
- 10. 函数内部
- 11. 函数属性与方法
- 12. 函数表达式
- 13. 递归
- 14. 尾调用优化
- 15. 闭包
- 16. 立即调用的函数表达式
- 17. 私有变量
第7章:迭代器与生成器
1. 迭代器模式
- 把实现了正式的Iterable接口的某些结构称为“可迭代对象”(iterator),可以通过迭代器Iterator消费。
- 可迭代对象:元素有限且具有无歧义的遍历顺序。
- 可迭代协议(实现Iterator接口)
- 要求同时具备两种能力:支持迭代的自我识别能力和创建实现Iterator接口的对象的能力。
- 必须暴露一个属性作为“默认迭代器”,而且这个属性必须使用特殊的Symbol.iterator作为键。
- 默认迭代器属性必须引用一个迭代器工厂函数,调用这个工厂函数必须返回一个新迭代器。
- 不需要显式调用工厂函数来生成迭代器。接收可迭代对象的原生语言特性包括:
- for-of循环
- 数组解构(不懂,看下面例子有点明白了)
// 数组解构
let [a, b, c] = arr;
console.log(a, b, c); // foo, bar, baz
- 扩展操作符
- Array.from()
- 创建集合
- 创建映射
- Promise.all()接收由期约组成的可迭代对象(期约是什么见第11章)
- Promise.race()接收由期约组成的可迭代对象
- yield*操作符,在生成器中使用(这个暂时也不懂)
- 迭代器协议
- 迭代器API使用next()方法在可迭代对象中遍历数据。
- next()方法返回迭代器对象IteratorResult包含两个属性:done和value。done是一个布尔值,表示是否还可以再次调用next()取得下一个值;value包含可迭代对象的下一个值。
- 自定义迭代器
- 提前终止迭代器
2. 生成器
- 生成器基础
- 生成器的形式是一个函数,函数名称前面加一个星号(*)表示它是一个生成器。
- 标识生成器函数的星号不受两侧空格的影响。
- 生成器函数声明:
function* generatorFn() { }
- 调用生成器函数会产生一个生成器对象。
- 通过yield中断执行
- 生成器可以用来作为默认迭代器。
- 可以提前终止生成器。可选的return()方法用于提前终止迭代器。
- 与迭代器不同,所有的生成器对象都有return()方法,只要通过它进入关闭状态,就无法恢复了。后续调用next()会显示done:true状态。
- throw()方法会在暂停的时候将一个提供的错误注入到生成器对象中。如果错误未被处理,生成器就会关闭。如果生成器对象还没有开始执行,那么调用throw()抛出的错误不会在函数内部被捕获,因为这相当于在函数块外部抛出了错误。
第8章:对象、类与面向对象编程
1. 理解对象
- 属性的类型:[[ ]]
- 数据属性
- 包含一个保存数据值的位置。值会从这个位置读取,也会写入到这个位置。
- 四个特性:[[Configurable]]、[[Enumerable]]、[[Writable]]、[[Value]]
- 修改属性默认值方法:Object.defineProperty(),实际情况中不太用得到。
- 访问器属性
- getter():读取访问器属性
- setter():设置访问器属性
- 四个特性:[[Configurable]]、[[Enumerable]]、[[Get]]、[[Set]]
- 访问器属性是不能直接定义的,必须使用Object.defineProperty()
- 数据属性
- 定义多个属性:Object.definedProperties()
let book = {};
Object.definedProperties(book,{
year_: {
value: 2023
},
edition: {
value: 1
}
})
- 读取属性的特性
- 使用Object.getOwnPropertyDescriptor()方法可以取得指定属性的属性描述符。这个方法接收两个参数:属性所在的对象和要取得其描述符的属性名。返回值是一个对象。
let descriptor = Object.getOwnPropertyDescriptor(book, "year_");
console.log(descriptor.value); // 2023
console.log(descriptor.configurable); // false
- Object.getOwnPropertyDescriptors()静态方法。这个方法实际上会在每个自有属性上调用Object.getOwnPropertyDescriptor()并在一个新对象中返回它们。
- 使用Object.getOwnPropertyDescriptor()方法可以取得指定属性的属性描述符。这个方法接收两个参数:属性所在的对象和要取得其描述符的属性名。返回值是一个对象。
- 合并对象:Object.assign()方法
- 对象标识及相等判定:Object.is()方法
- 增强的对象语法
- 属性值简写:只要使用变量名就会自动被解释为同名的属性键。
- 可计算属性
- 简写方法名
- 对象解构
- 嵌套解构
- 部分解构
- 参数上下文匹配
2. 创建对象
-
工厂模式
function createPerson(name, age, job) {let o = new Object();o.name = name;o.age = age;o.job = job;o.sayName = function() {console.log(this.name);};return o; }
-
构造函数模式
function Person(name, age, job){this.name = name;this.age = age;this.job = job;this.sayName = function() {console.log(this.name);}; }
- 构造函数也是函数,任何函数只要使用new操作符调用就是构造函数。如果没有使用new操作符调用,会将属性和方法添加到window对象。通过call()调用函数的调用方式,可以将特定对象指定为作用域。
- 构造函数的问题是,其定义的方法会在每个实例上都创建一遍。为解决这个问题,可以把函数定义转移到构造函数外部。新问题:全局作用域被搞乱了,导致自定义类型引用的代码不能很好地聚集在一起,解决方法是原型模式。
-
原型模式
function Person() {} Person.prototype = {name: "Nicholas",age: 29,job: "Software Engineer",sayName() {console.log(this.name);} };
- 每个函数都会创建一个prototype属性,叫原型对象。它上面定义的属性和方法可以被对象实例共享。
- 原来在构造函数中直接赋给对象实例的值,可以直接赋值给它们的原型。
- 注意理解:实例与构造函数原型之间有直接的联系,但实例与构造函数之间没有。
- 原型层级:通过对象访问属性时,会按照属性名称开始搜索,从对象实例开始搜索,如果没有找到,搜索会沿着指针进入原型对象,然后在原型对象上进行搜索。这就是原型用于在多个对象实例间共享属性和方法的原理。
- 只要给对象实例添加一个属性,这个属性就会遮蔽(shadow)原型对象上的同名属性,不会修改但会屏蔽对原型对象的访问。使用delete操作符删除实例上的这个属性,则可以继续搜索原型对象。
- 原型和in操作符
- in操作符,只要通过对象可以访问,就返回true。
- hasOwnProperty(),只有属性存在于实例上时才返回true。
- 属性枚举顺序
- for-in循环和Object.keys()的枚举顺序是不确定的。
- Object.getOwnPropertyNames()、Object.getOwnPropertySymbols()和Objetc.assign()的枚举顺序是确定性的。
-
对象迭代
- 将对象内容转换为序列化的可迭代格式的两个静态方法:Object.values()和Object.entries()。注意:符号属性会被忽略。
- 其他原型语法:Person.prototype={};
- 即使实例在修改原型之前已经存在,任何时候对原型对象所做的修改也会在实例上反映出来。
- 实例只有指向原型的指针,没有指向构造函数的指针。
- 原生对象原型也可以修改,但是不建议这么做,推荐做法是创建一个自定义类,继承原生原型。
- 原型的问题主要体现在操作包含引用值的属性时。
3. 继承:依靠原型链实现
- 原型链
- 构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型有一个属性指回构造函数,而实例有一个内部指针指向原型。
- 当前原型是另一个原型的实例,这样就组成了一个原型链。
- 默认原型:默认情况下,所有引用类型都继承自Object。
- 原型与继承关系:原型与实例的关系可以通过instanceof操作符或者isPrototypeOf()方法来确定。
- 子类增加父类没有的方法,必须在原型赋值之后在添加到原型上。
- 注意:以字面量方式创建原型方法会破坏之前的原型链,因为这相当于重写。
- 原型链的问题:
- 包含引用值时
- 子类型实例化时不能给父类型构造函数传参
- 盗用构造函数(解决原型链的问题)
- 思路:在子类构造函数中调用父类构造函数。
- 使用call()或者apply()方法。
- 盗用构造函数的一个优点是可以在子类构造函数中向父类构造函数传参。
- 盗用构造函数的缺点:
- 必须在构造函数中定义方法,因此函数不能重用。
- 子类也不能访问父类原型上定义的方法,因此所有类型只能使用构造函数模式。
- 组合继承
- 原型式继承:Object.create(),第二个参数用来新增属性,新增的属性会遮蔽原型对象上的同名属性。
let person = {name:"wenshuo",friends:["yaya","xiaoxiao"] } let anotherPerson = Object.create(person,{name:{value:"Greg"} });
- 寄生式继承(首倡的一种模式)
function object(o){function F(){}F.prototype = o;return new F(); } function createAnother(original){let clone = object(original);clone.sayHi = function (){console.log("Hi");}return clone; }
- 寄生式组合继承(没看明白)
4. 类class
- 类定义
- 类声明:class Person { }
- 类表达式:const Animal = class { };
- 函数声明可以提升,类声明不可以提升
- 函数受函数作用域限制,类受块作用域限制。
- 类构造函数
- 构造函数的定义不是必需的
- 类实例化时传入的参数会用作构造函数的参数。如果不需要参数,则类名后面的括号也是可选的。
- 调用类构造函数必须使用new操作符
- 把类当成特殊函数,可以把类作为参数传递
- 实例、原型和类成员
- 实例成员:每次通过new调用类标识符时,都会执行类构造函数。
- 原型方法与访问器:为了在实例间共享方法,类定义语法把在类块中定义的方法作为原型方法。
- 静态类方法:用于执行不特定于实例的操作,也不要求存在类的实例。
- 非函数原型和类成员
class Person{sayName(){console.log(`${Person.greeting} ${this.name}`)} } // 在类上定义数据成员 Person.greeting = "My name is"; // 在原型上定义数据成员 Person.prototype.name = "Jake"; let p = new Person(); p.sayName();
- 迭代器与生成器方法
- 继承
- 继承基础
- 使用extends关键字,不仅可以继承一个类,也可以继承普通的构造函数。
- 构造函数、HomeObject和super():super的一些注意事项
- 抽象基类:可供其他类继承,但本身不会被实例化。
- 继承内置类型
- 类混入(好多js框架已经抛弃了混入模式,转入了组合模式。组合胜过继承。)
- 继承基础
第10章:函数
1. 函数定义的方式有:函数声明、函数表达式、箭头函数,Function构造函数。
2.箭头函数(=>)
- 不能使用arguments、super和new.target,也不能用作构造函数,也没有prototype属性。
3. 函数名:就是指向函数的指针。
- 一个函数可以有多个名称。
- 使用不带括号的函数名会访问函数指针,而不会执行函数。
- 所有函数对象都会暴露一个制度的name属性。如果函数是一个获取函数、设置函数,或者使用bind()实例化,那么标识符前面会加上一个前缀。
4. 理解参数
- ECMAScript函数既不关心传入的参数个数,也不关心这些参数的数据类型。
- 使用function关键字定义(非箭头)函数时,可以在函数内部访问arguments对象,从中取得传进来的每个参数值。
- 注意:ECMAScript中的所有参数都是按值传递的。不可能按引用传递参数。如果把对象作为参数传递,那么传递的值就是这个对象的引用。
5. 没有重载
- 如果在ECMAScript中定义了两个同名函数,则后定义的会覆盖先定义的。
6. 默认参数值
- 显式定义默认参数:在函数定义的参数后面用=就可以为参数赋一个默认值。
- 给参数传undefined相当于没有传值,可以通过这种方式利用默认值。
- 使用默认参数时,arguments对象的值不反映参数的默认值,只反映传给函数的参数。修改命名参数也不会影响arguments对象,它始终以调用函数时传入的值为准。
- 参数是按顺序初始化的,遵循“暂时性死区”规则,即前面定义的函数不能引用后面定义的。
7. 参数扩展与收集
- 扩展参数:扩展操作符可以用于调用函数时传参。
- 收集参数:扩展操作符也可以用于定义函数参数。把不同长度的独立参数组合为一个数组。
8. 函数声明与函数表达式
- 在任何代码执行之前,会先读取函数声明,并在执行上下文中生成函数定义。这个过程叫做函数声明提升。
- 函数表达式必须等到代码执行到它那一行,才会在执行上下文中生成函数定义。
9. 函数作为值
- 函数名在ECMAScript中就是变量,所以函数可以用在任何可以使用变量的地方。
10. 函数内部
- arguments:类数组对象。该对象有一个callee属性,指向arguments对象所在函数的指针。
// 让函数逻辑与函数名解耦 function factorial(num) {if (num <= 1) {return 1;} else {return num * arguments.callee(num - 1);} }
- this
- 在标准函数中,this引用的是把函数当成方法调用的上下文对象。
- 在箭头函数中,this引用的是定义箭头函数的上下文。
- caller:
- 函数的一个属性,引用的是调用当前函数的函数,如果是在全局作用域中调用的则为null。
- 如果要降低耦合度可以通过arguments.callee.caller来引用相同的值。
- new.target:函数的一个属性,检测函数是否使用new关键字调用的。
11. 函数属性与方法
- 每个函数都有两个属性:length和prototype。
- length:保存函数定义的命名参数的个数。
- prototype:是保存引用类型所有实例方法的地方。
- 函数的两个方法:apply()和call(),这两个方法都会以指定的this值来调用函数。
- apply():两个参数,函数内的this值和一个参数数组。
- call():与apply()作用一样,传参形式不同。第一个参数也是this值,剩下的要传给被调用函数的参数则是逐个传递的,也就是说必须将参数一个一个地列出来。
12. 函数表达式
- 函数表达式与函数声明最大的区别就是,函数声明可以提升,函数表达式不可以。
13. 递归
- 递归函数通常的形式是一个函数通过名称调用自己。
- 在编写递归函数时,arguments.callee是引用当前函数的首选。(严格模式下不可访问arguments.callee)
- 因此可以使用明明函数表达式(named function expression),严格模式和非严格模式下都可以使用。
const factorial = (function f(num){if(num <= 1){return 1;}else{return num*f(num-1);} });
14. 尾调用优化
- 尾调用:外部函数的返回值是一个内部函数的返回值。
15. 闭包
- 参考链接
- 闭包指的是那些引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现的。
- 闭包可以让开发者从内部函数访问外部函数的作用域。
- 每个函数在调用时都会自动创建两个特殊变量:this和arguments。内部函数永远不可能直接访问外部函数的这两个变量。先把外部函数的this保存到变量that中再访问就可以了。let that = this;that.xxx
16. 立即调用的函数表达式
- 立即调用的匿名函数又被称作立即调用的函数表达式(IIFE, Immediately Invoked Function Expression)。类似于函数声明,但由于被包含在括号中,所以会被解释为函数表达式。使用IIFE可以模拟块级作用域。
(function(){// 块级作用域 })();
17. 私有变量
- 任何定义在函数或块中的变量,都可以认为是私有的,因为在这个函数或块的外部无法访问其中的变量。
- 私有变量包括函数参数、局部变量,以及函数内部定义的其它函数。
- 特权方法是能够访问函数私有变量(及私有函数)的公有方法。特权方法可以在构造函数中实现,也可以使用静态私有变量来实现。
- 每次调用构造函数都会重新创建一套变量和方法,所以每个实例都会重新创建一遍新方法。
- 静态私有变量可以利用原型更好地重用代码,只是每个实例没有自自己的私有变量。
- 模块模式
-
单例对象
let singleton = { name:value, method(){ // 方法的代码 } };
-
模块模式是在单例对象基础上加以扩展,使其通过作用域链来关联私有变量和特权方法。
-
- 模块增强模式
- 另一个利用模块模式的做法是在返回对象之前先对其进行增强。
- 这适合单例对象需要是某个特定类型的实例,但又必须给它添加额外属性或方法的场景。
相关文章:
JavaScript学习笔记(三)
文章目录 第7章:迭代器与生成器1. 迭代器模式2. 生成器 第8章:对象、类与面向对象编程1. 理解对象2. 创建对象3. 继承:依靠原型链实现4. 类class 第10章:函数1. 函数定义的方式有:函数声明、函数表达式、箭头函数&…...

文鼎创智能物联云原生容器化平台实践
作者:sekfung,深圳市文鼎创数据科技有限公司研发工程师,负责公司物联网终端平台的开发,稳定性建设,容器化上云工作,擅长使用 GO、Java 开发分布式系统,持续关注分布式,云原生等前沿技…...

深入了解SpringMVC框架,探究其优缺点、作用以及使用方法
一、什么是Spring MVC SpringMVC是一种基于Java的Web框架,与Spring框架紧密结合,用于开发具备WebApp特性的Java应用程序。Spring MVC是Spring Framework的一部分,因此它具有与Spring框架相同的特性和理念。 二、SpringMVC的优缺点 1. 优点…...

Git教程(一)
1、Git概述 1.1 、Git历史 同生活中的许多伟大事件一样,Git 诞生于一个极富纷争大举创新的年代。Linux 内核开源项目有着为数众广的参与者。绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务上(1991-2002年间)…...

数据结构篇三:双向循环链表
文章目录 前言双向链表的结构功能的解析及实现1. 双向链表的创建2. 创建头节点(初始化)3. 创建新结点4. 尾插5. 尾删6. 头插7. 头删8. 查找9. 在pos位置前插入10. 删除pos位置的结点11. 销毁 代码实现1.ListNode.h2. ListNode.c3. test.c 总结 前言 前面…...

day10 TCP是如何实现可靠传输的
TCP最主要的特点 1、TCP是面向连接的运输层协议。( 每一条TCP连接只能有两个端点(endpoint),每一条TCP连接只能是点对点的(一对一)) 2、TCP提供可靠交付的服务。 3、TCP提供全双工通信。 4…...
Python | 人脸识别系统 — 背景模糊
本博客为人脸识别系统的背景模糊代码解释 人脸识别系统博客汇总:人脸识别系统-博客索引 项目GitHub地址:Su-Face-Recognition: A face recognition for user logining 注意:阅读本博客前请先参考以下博客 工具安装、环境配置:人脸…...

YOLOv5+单目测量物体尺寸(python)
YOLOv5单目测量尺寸(python) 1. 相关配置2. 测距原理3. 相机标定3.1:标定方法1(针对图片)3.2:标定方法2(针对视频) 4. 相机测距4.1 测距添加4.2 细节修改(可忽略…...

C++异常
C异常 提到异常,大家一定不陌生,在学习new关键字的时候就提到了开空间失败会导致抛异常。其实异常在我们生活中的使用是很多的,有些时候程序发生错误以后我们并不希望程序就直接退出,针对不同的情况,我们更希望有不同的…...
Java中的字符串是如何处理的?
Java中的字符串是通过字符串对象来处理的。字符串是一个类,可以创建一个字符串对象,并在该对象上调用一系列方法来操作该字符串。 Java中的字符串是不可变的,这意味着一旦创建了一个字符串对象,就无法修改它的值。任何对字符串对…...
【热门框架】怎样使用Mybatis-Plus制作标准的分页功能
使用 Mybatis-Plus 实现标准的分页功能需要使用 Page 类来进行分页操作。具体步骤如下: 引入 Mybatis-Plus 依赖 在 Maven 项目中,在 pom.xml 文件中引入 Mybatis-Plus 的依赖: <dependency><groupId>com.baomidou</groupId&g…...
Java方法引用:提高代码可读性和可维护性
前言 在Java 8中,可以使用方法引用(Method Reference)来简化Lambda表达式。方法引用是一种更简洁易懂的语法形式,可以通过指定方法的名称代替Lambda表达式。 本文将介绍方法引用的用法和实现原理,并结合代码案例详细…...
如何使用CSS和JS实现一个响应式的滚动时间轴
随着互联网的发展,网站的界面设计越来越重要。吸引用户的关注、提高用户体验已经成为了许多网站的目标。而在实现各种复杂的界面效果中,CSS与JS的组合无疑是开发者的得力工具。本文将介绍如何使用CSS和JS实现一个响应式的滚动时间轴。 1.需求分析 在开…...

Feign组件的使用及开发中使用方式
在微服务的服务集群中服务与服务之间需要调用暴露的服务.那么就需要在服务内部发送http请求, 我们可以使用较为老的HttpClient实现,也可以使用SpringCloud提供的RestTemplate类调用对应的方法来发送对应的请求。 说明: 现在有两个微服务一个是…...
html css 面试题
1. 如何理解HTML语义化 1,可读性,易读性 2,seo搜索引擎更容易读懂 2,哪些是块元素,哪些是内联元素 1:div,h1,table,ul,p 2:span, img…...

LeetCode_双指针_中等_24.两两交换链表中的节点
目录 1.题目2.思路3.代码实现(Java) 1.题目 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 示例 1&a…...

【openGauss实战11】性能报告WDR深度解读
📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…...
Vue3实现打字机效果
typeit 介绍 typeit是一款轻量级打字机特效插件。该打印机特效可以设置打字速度,是否显示光标,是否换行和延迟时间等属性,它可以打印单行文本和多行文本,并具有可缩放、响应式等特点。官方文档 安装 # npm npm install typeit # …...
maven无法依赖spring-cloud-stater-zipkin如何解决?
当 Maven 无法依赖 spring-cloud-starter-zipkin 时,您可以尝试以下方法解决: 确保拼写正确:请检查项目中的 pom.xml 文件,确保依赖的拼写正确。正确的依赖名称应为:spring-cloud-starter-zipkin。添加 Spring Cloud …...
实战踩坑---MFC---CreateEvent
使用事件CreateEvent注意事项 HANDLECreateEvent( LPSECURITY_ATTRIBUTESlpEventAttributes,// 安全属性 BOOLbManualReset,// 复位方式 BOOLbInitialState,// 初始状态 LPCTSTRlpName // 对象名称 );[1] 参数 lpEventAttributes[输入] 一个指向SECURITY_ATTRIBUTES结构…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
FTXUI::Dom 模块
DOM 模块定义了分层的 FTXUI::Element 树,可用于构建复杂的终端界面,支持响应终端尺寸变化。 namespace ftxui {...// 定义文档 定义布局盒子 Element document vbox({// 设置文本 设置加粗 设置文本颜色text("The window") | bold | color(…...

CSS 工具对比:UnoCSS vs Tailwind CSS,谁是你的菜?
在现代前端开发中,Utility-First (功能优先) CSS 框架已经成为主流。其中,Tailwind CSS 无疑是市场的领导者和标杆。然而,一个名为 UnoCSS 的新星正以其惊人的性能和极致的灵活性迅速崛起。 这篇文章将深入探讨这两款工具的核心理念、技术差…...

二叉树-144.二叉树的前序遍历-力扣(LeetCode)
一、题目解析 对于递归方法的前序遍历十分简单,但对于一位合格的程序猿而言,需要掌握将递归转化为非递归的能力,毕竟递归调用的时候会调用大量的栈帧,存在栈溢出风险。 二、算法原理 递归调用本质是系统建立栈帧,而非…...