【Vue-4小时速通01-ES6】

1.var和let的区别

1.1作用域与有效范围
var 在函数或全局作用域中声明变量,无论在块级作用域内外都可以访问。
var 即使在块级作用域外部访问,仍然能获取到结果。
let 在块级作用域内声明变量,仅在其所在的作用域中有效。
let 如果在作用域外访问,会抛出 ReferenceError
// 示例
 {
     var a = 10;
     let b = 20;
 }
 console.log(a); // 10 (var 在全局或函数作用域内有效)
 console.log(b); // ReferenceError: b is not defined (let 仅在块级作用域内有效)
1.2重复定义
var: 可以在同一个作用域内多次声明同名变量,而不会抛出错误,后面声明的变量会覆盖前面的值。
let: 不允许在同一作用域内重复声明同名变量,重复声明会抛出 SyntaxError。
// 示例
 {
        var a = 1;
        var a = 2;  // 无报错,a 赋值为 2
        console.log(a); // 2
        let b = 1;
        //let b = 2; //  报错Uncaught SyntaxError: Identifier 'b' has already been declared
        console.log(b); // 1
   }
1.3变量提升
 var: 变量声明会被提升到作用域的顶部,但赋值不会被提升,因此会在使用变量前显示为 undefined。
 let: 变量声明不会被提升,尝试在声明前访问会抛出 ReferenceError,因为变量在声明之前处于“暂时性死区(TDZ)。
// 示例
{
    console.log(a); // undefined (var 变量会提升,初始化为 undefined)
    var a = 10;
    console.log(b); // Uncaught ReferenceError: Cannot access 'b' before initialization
    let b = 10; // let 变量不会提升,访问前会抛出错误
 }
1.4块级作用域与闭包
var在块级作用域内声明的变量会被提升到函数或全局作用域,因此可能会影响闭包的行为。
let创建的是块级作用域变量,避免了 var 在闭包中的不期望行为。
// 示例
for (var i = 0; i < 3; i++) {
        setTimeout(function () {
            console.log(i); // 输出 3, 由于 var 的提升,i 的值在 for 循环外部是 3
        }, 100);
    }

 for (let j = 0; j < 3; j++) {
        setTimeout(function () {
            console.log(j); // 输出 0, 1, 2, 因为 let 会在每次迭代中创建新的作用域
        }, 100);
    }
1.5总结
var 和 let 的主要区别在于作用域、变量提升、以及是否支持重复定义。
var 是函数作用域或全局作用域,且会提升到顶部;let 是块级作用域,不会提升。
let 在闭包和异步代码中表现得更稳定,避免了 var 可能带来的问题。
// 示例
 {
     var a = 10;
     let b = 20;
 }
 console.log(a); // 10 (var 在全局或函数作用域内有效)
 console.log(b); // ReferenceError: b is not defined (let 仅在块级作用域内有效)

2.const 与 let 的差异

const: 声明的是常量,必须在声明时初始化,且值不能修改。
但 const 声明的是引用类型的对象时,对象的内容是可变的,只是不能重新赋值给其他对象。
const a = 10;
a = 20; // Uncaught TypeError: Assignment to constant variable.
console.log(a)

const obj = {name: 'tom',age: 18};
obj.age = 22;
console.log(obj) // {name: 'tom', age: 22}
obj = {}; // Uncaught TypeError: Assignment to constant variable.
总结:
    var 和 let 的主要区别在于作用域、变量提升、以及是否支持重复定义。
    var 是函数作用域或全局作用域,且会提升到顶部;let 是块级作用域,不会提升。
    let 在闭包和异步代码中表现得更稳定,避免了 var 可能带来的问题。

3.解构

3.1数组解构
解构赋值允许从数组中提取值并赋给变量。通过解构语法,我们可以更简洁地获取数组元素。
let arr = [1, 2, 3]
let [a, b, c] = arr
// 等价于
// let a = arr[0]
// let b = arr[1]
// let c = arr[2]
console.log(a)
console.log(b)
console.log(c)
3.2对象解构
对象解构允许从对象中提取值并赋给变量,变量名必须与对象的属性名相同。
let obj = { name: 'tom', age: 18 };
let { name, age } = obj
// 等价于
// let name = obj.name 
// let age = obj.age
console.log(name)
console.log(age)

4.链判断

可选链在判断中间属性是否存在时,会自动短路并返回 undefined,避免了显式的检查
可选链允许我们在访问深层嵌套对象的属性时避免因中间某一属性为 null 或 undefined 而导致的错误。
let content = null;
// 传统的链式判断
const username = (content && content.body && content.body.user && content.body.user.username) || 'defalut';
console.log(username)
//使用可选链(?.)
const uname = content?.body?.user?.username || 'default';
console.log(uname)

5.参数默认值

传统的参数默认值 使用 || 操作符来为参数提供默认值,但当参数为 0 或 false 时,也会被误判为“假值”。
function add(a, b) {
    b = b || 10;  // 如果 b 为 falsy 值(例如 0),则默认赋值为 10
   return a + b;
}
console.log(add(10)); // 20
//使用 ES6 的默认参数值 通过在函数声明时直接为参数提供默认值,避免了上面的问题。此方法仅在参数为 undefined 时生效,而不是 null 或 0 等其他“假值”。
function add2(a, b = 10) {
    return a + b;
 }
console.log(add2(10)); // 20

6.箭头函数

6.1一个参数 箭头函数提供了更简洁的函数表达式,且默认绑定函数的 this
let print1 = function (obj) {
  console.log(obj);
};
let print2 = obj => console.log(obj); // 箭头函数,简写形式
6.2两个参数 如果有多个参数,则使用括号包裹参数。
let sum = function (a, b) {
    return a + b;
}
let sum2 = (a, b) => a + b;
6.3当箭头函数有多行语句时,必须使用大括号 {} 并明确 return
let sum3 = (a, b) => {
  c = a + b;
  return c;
};
6.4当箭头函数只有一行时,可以省略 return 和大括号,简洁书写
let sum4 = (a, b) => a + b;

7.字符串模板

ES6 引入了模板字符串(也叫模板字面量),它允许我们在字符串中直接嵌入变量或表达式,使用反引号(`)包裹,并通过 ${} 插入变量。
7.1 普通的字符串拼接
let person = {name:'tom',age: 22}
let {name,age} = person
let str = "姓名:" + name + ", 年龄:" + age;
console.log(str); // 姓名:Tom, 年龄:22
7.2 字符串模板
let person = {name:'tom',age: 22}
let {name,age} = person
let str2 = `姓名:${name}, 年龄:${age}`;
console.log(str2); // 姓名:Tom, 年龄:22
7.3多行支持
let multilineStr = `这是一行
    这是第二行
    这是第三行`;
console.log(multilineStr);  // 打印结果为3行 
7.4字符串模板中的表达式
let num1 = 5;
let num2 = 10;
let result = `结果:${num1 + num2}`;
console.log(result); // 结果:15
7.5总结
字符串模板支持变量、表达式嵌入以及多行字符串。
使用字符串模板(Template Literals)比传统的字符串拼接更简洁和易于维护。
传统字符串拼接虽然仍然有效,但随着代码复杂度增加,使用模板字符串会使代码更具可读性和可维护性。

8.Promise用法

Promise 是 JavaScript 中用于处理异步操作的一个对象,代表了一个操作的最终完成(或失败)及其结果值。
Promise 有三种状态:
pending:等待状态,初始状态,既不是成功,也不是失败。
fulfilled:成功状态,表示操作成功完成。
rejected:失败状态,表示操作失败
8.18.1基础使用
let promise = new Promise((resolve,reject)=>{
    let dataFetched = true; // 模拟数据是否获取成功
    if(dataFetched){
        resolve("数据获取成功!");
   }else{
        reject("数据获取失败!");
   }
})
promise.then((message)=>console.log(message)).catch((error)=>{console.log(error)})
8.2链式调用多个.then()
let fetchData = new Promise((resolve)=>setTimeout(()=>resolve("8.2数据获取成功!"),1000))
fetchData.then((message)=>{
   console.log(message);
    return "8.2数据获取成功!";
}).then((processedData)=>{
   console.log(processedData);
    return "8.2保存数据!";
}).then((saveData)=>{
   console.log(saveData)
}).catch((error)=>{
  console.log(error)
})

打印结果:
8.2数据获取成功1!
ES6.html:200 8.2数据获取成功2!
ES6.html:203 8.2保存数据3!
通过 .then() 实现多个异步操作的顺序执行。
Promise 支持链式调用,即一个 .then() 返回的值会传递给下一个 .then()
8.3Promise.all()
 Promise.all() 用于并行执行多个异步操作,只有所有 Promise 都完成时,它才会返回。  
let fetchData1 = new Promise((resolve) => setTimeout(() => resolve("数据1获取成功"), 1000));
let fetchData2 = new Promise((resolve) => setTimeout(() => resolve("数据2获取成功"), 2000));

Promise.all([fetchData1, fetchData2])
  .then((results) => {
      console.log(results); // 输出:["数据1获取成功", "数据2获取成功"]
    })
  .catch((error) => {
      console.error(error); // 如果其中一个失败,会进入这里
});
8.4Promise.race()
Promise.race() 也是用于并行执行多个异步操作,但它会返回第一个完成的 Promise
let fetchData3 = new Promise((resolve) => setTimeout(() => resolve("数据1获取成功"), 1000));
let fetchData4 = new Promise((resolve) => setTimeout(() => resolve("数据2获取成功"), 500));

Promise.race([fetchData3, fetchData4])
   .then((result) => {
      console.log(result);  // 输出:数据2获取成功
    })
    .catch((error) => {
      console.error(error);
});
8.5总结
Promise 基本概念:
Promise 代表异步操作的最终完成(或失败)及其结果值。
resolve() 用于标记成功并返回值,reject() 用于标记失败并返回错误。
Promise 初始状态为 pending,可以通过 resolve 转变为 fulfilled,通过 reject 转变为 rejected。
Promise 链式调用:
通过 .then() 处理成功的结果,.catch() 处理失败的错误。
Promise 支持链式调用,即一个 .then() 返回的值会传递给下一个 .then()。
并行操作:
Promise.all() 用于并行执行多个异步操作,等待所有 Promise 都完成后才会返回。
Promise.race() 用于并行执行多个异步操作,只返回第一个完成的 Promise。
优点:
Promise 提供了比回调函数更优雅的方式来处理异步操作,避免了回调地狱问题。
Promise 的链式调用使得多个异步操作可以顺序执行,逻辑更清晰。
Promise 的并行控制(Promise.all 和 Promise.race)使得多个异步任务可以在并行时得到很好的控制。
注意:
    如果在链式调用中某一 Promise 被拒绝,后续的 .then() 不会继续执行,进入 .catch() 捕获错误。

9.Async 和 Await

async 和 await 是 JavaScript 中用于处理异步操作的语法糖,它们基于 Promise,使得异步代码更具可读性和同步风格,减少了回调函数和 .then() 链式调用的复杂性。
9.1async 函数
async 关键字用于声明一个函数,使其成为异步函数。异步函数返回一个 Promise 对象,且在函数内部,可以使用 await 来等待异步操作完成。
let fetchData01 = async () => { return "数据获取成功!" }
fetchData01().then((message) => console.log(message))
9.2 await 关键字
await 会暂停函数的执行,直到 Promise 完成。
await 关键字只能在 async 函数内部使用,用于等待一个 Promise 完成,并返回其结果。
await 会等待 Promise 完成,如果 Promise 被 resolve,返回的值会赋给变量;如果 Promise 被 reject,会抛出异常。
let fetchData02 = async () => {
   let result = await new Promise((resolve) => {
      setTimeout(() => resolve("9.2获取数据成功!"), 1000)
   })
   console.log(result)
}
fetchData02()
9.3 async/await 错误处理
通过 try/catch 可以捕获 async 函数中 await 产生的错误,与同步代码处理异常的方式相同
let fetchData03 = async () => {
   try {
      let result = await new Promise((resolve, reject) => {
        setTimeout(() => reject("9.3获取数据失败!"), 1000)
      })
      console.log(result)
   } catch (error) {
       console.log(error)
    }
}
fetchData03()
9.
在这里插入代码片
9.4多个异步操作并行执行
let fetchData04 = async () => {
   let promise01 = new Promise((resolve) => setTimeout(() => resolve("9.4获取数据成功01!")), 1000)
   let promise02 = new Promise((resolve) => setTimeout(() => resolve("9.4获取数据成功02!")), 1000)
   let result = await Promise.all([promise01, promise02])
   console.log(result)
}
fetchData04()
9.5多个异步操作按顺序执行
let fetchData05 = async () => {
  let promise03 = await new Promise((resolve) => setTimeout(() => resolve("9.5获取数据成功01!")), 1000)
  console.log(promise03)
  let promise04 = await new Promise((resolve) => setTimeout(() => resolve("9.5获取数据成功02!")), 1000)
  console.log(promise04)
}
fetchData05()
9.6避免回调地狱
回调地狱:非常不推荐,代码难以维护,错误处理复杂。
链式的.then调用:比回调地狱更清晰,但当异步操作较多时,.then() 链条会变得长且难以调试。
async/await:最简洁和直观,尤其适合多个异步操作的顺序执行。通过 try/catch 可以像同步代码一样处理错误,强烈推荐使用。
let loadData01 = (callback) => {
        setTimeout(() => {
            console.log("9.6加载数据成功!")
            callback(null, '--加载数据--')
        }, 1000)
    }
let processData01 = (data, callback) => {
     setTimeout(() => {
        console.log("9.6处理数据成功!")
        callback(null, `--${data} 处理数据--`)
     }, 1000)
 }
let saveData01 = (data, callback) => {
    setTimeout(() => {
      console.log("9.6保存数据成功!")
      callback(null, `--${data} 保存数据--`)
    }, 1000)
}
// 回调地狱:每个操作依赖前一个操作的完成
loadData01((err, data) => {
   if (err) {
        console.error('数据加载失败:', err)
        return
   }
  processData01(data, (err, processedData) => {
        if (err) {
          console.error('数据处理失败:', err)
          return
        }
        saveData01(processedData, (err, savedData) => {
          if (err) {
            console.error('数据保存失败:', err)
            return
           }
         console.log('数据处理完成:', savedData)
      })
  })
})
    
//使用 Promise  避免回调地狱
let loadData02 = ()=> {
   return new Promise((resolve, reject) => {
       setTimeout(() => {
           console.log("9.6Promise加载数据成功!")
            resolve('--加载数据--')
       }, 1000)
  })
}

let processData02 = (data)=> {
   return new Promise((resolve, reject) => {
       setTimeout(() => {
           console.log("9.6Promise处理数据成功!")
           resolve( `--${data} 处理数据--`)
        }, 1000)
   })
}

let saveData02 = (data)=> { 
   return new Promise((resolve, reject) => {
      setTimeout(() => {
          console.log("9.6Promise保存数据成功!")
          resolve(`--${data} 保存数据--`)
      }, 1000)
  })
}
    
//使用链式的.then调用,避免回调地狱
loadData02()
   .then(data => processData02(data))
   .then(processedData => saveData02(processedData))
   .then(savedData => {
       console.log('9.6then数据处理完成:', savedData)
   })
   .catch(error => {
      console.error('9.6then数据处理失败:', error)
 })
    
//使用 async/await避免回调地狱
let loadData03 = async () =>{
   try {
     const data = await loadData02()
     const processedData = await processData02(data)
     const savedData = await saveData02(processedData)
     console.log('9.6await数据处理完成:', savedData)
   } catch (error) {
      console.error('9.6await数据处理失败:', error)
  }
}
loadData03()

10.模块化 ES6 Module

ES6 Module 模块功能主要由两个命令构成:export 和 import。
export 命令用于规定模块的对外接口,import 命令用于输入其他模块提供的功能
10.1命名导出(Named Export)
可以导出多个变量或函数。导出的名称需要与导入时的名称一致。
//写法一
//导出变量
export const PI = 3.14;
//导出函数
export function add(a, b) {
   return a + b;
}
export function subtract(a, b) {
    return a - b;
}
//导出类
export class Person {
   constructor(name, age) {
       this.name = name
       this.age = age
   }       
   sayHello() {
      console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`)
   }
}
//写法二
//导出变量
const PI = 3.14;
export {PI}
//导出函数
function add(a, b) {
   return a + b;
}
function subtract(a, b) {
   return a - b;
}
export{add,subtract}
10.2默认导出(Default Exports)
默认导出可以是一个函数、对象、类等。每个模块只能有一个默认导出。
//greet.js
//默认导出变量
export default 10
const person = {
	name: 'Amy',
	age: 20,
}
export default person
//默认导出函数
export default function greet(name) {
	return `Hello, ${name}!`;
}
//默认导出类
export default class Person {
	constructor(name, age) {
		this.name = name
		this.age = age
	}
	sayHello() {
		console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`)
	}
}
10.3命名导入(Named Import)
导入时使用 {} 来指定要导入的变量或函数,名称必须与导出的名称一致。
// app.js
import { add, subtract, PI } from './math.js';

console.log(add(1, 2)); // 3
console.log(subtract(5, 3)); // 2
console.log(PI); // 3.14
10.4默认导入(Default Imports)
导入时不使用 {},可以给默认导入的内容起任何名称。
// app.js
import greet from './greet.js';

console.log(greet('Tom'));       // "Hello, Tom!"
10.5批量导出和导入:可以通过 export * from 来批量导出一个模块中的所有导出内容。
// math.js
export function add(a, b) {
	return a + b;
}
export function subtract(a, b) {
	return a - b;
}
export const PI = 3.14;
export * from './math.js';

// app.js
import * as math from './index.js';

console.log(math.add(1, 2)); // 3
console.log(math.subtract(5, 3)); // 2
console.log(math.PI); // 3.14
10.6同时导入
// app.js
import greet, { add, subtract, PI } from './math.js';

console.log(greet('Tom')); // "Hello, Tom!"
console.log(add(1, 2)); // 3
console.log(subtract(5, 3)); // 2
console.log(PI); // 3.14
10.7导出导入时起别名 可以在导入时给变量或函数起别名。
// app.js
import { add as addition, subtract as subtraction, PI as pi } from './math.js';

console.log(addition(2, 3));     // 5
console.log(subtraction(5, 3));  // 2
console.log(pi);                 // 3.14
10.8export 与 import 的复合写法
如果在一个模块之中,先输入后输出同一个模块,import 语句可以与 export 语句写在一起。
export { foo, bar } from 'my_module'

// 可以简单理解为
import { foo, bar } from 'my_module'
export { foo, bar }
10.9异步导入(动态导入)
// app.js
// 动态导入
import('./math.js').then(math => {
    console.log(math.add(1, 2));       // 3
    console.log(math.PI);              // 3.14
});
10.10总结
命名导出(Named Export):用于导出多个功能,导入时需要使用相同的名称。
默认导出(Default Export):每个模块只能有一个默认导出,导入时可以使用任意名称。
批量导入和导出:通过 export * 可以批量导出,使用 import * as 来导入所有内容。
动态导入:使用 import() 可以按需加载模块,实现代码分割。

模块化使得功能单元可以被不同的文件复用,减少了冗余代码。
通过命名空间(模块),不同文件的函数、变量等不会发生命名冲突。
模块化可以将代码分成不同的文件,每个文件负责不同的功能,增强了代码的可维护性。

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

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

相关文章

【数据集】生菜病害检测数据集530张6类YOLO+VOC格式

数据集格式&#xff1a;VOC格式YOLO格式 压缩包内含&#xff1a;3个文件夹&#xff0c;分别存储图片、xml、txt文件 JPEGImages文件夹中jpg图片总计&#xff1a;530 Annotations文件夹中xml文件总计&#xff1a;530 labels文件夹中txt文件总计&#xff1a;530 标签种类数&#…

设计模式2

23中设计模式分类 创建型模式&#xff1a;对象实例化的模式&#xff0c;创建型模式用于解耦对象的实例化过程。&#xff08;对象的创建和对象的使用分离&#xff09; 5种&#xff1a;单例模式、工厂模式、抽象工厂模式、原型模式、建造者模式 结构型模式&#xff1a;把类或对…

CSS边框的样式

边框阴影 让元素更有立体感 img {box-shadow: 2px 10px 5px 20px #ff0000;border-radius: 44px;}语法&#xff1a;box-shadow&#xff1a;值1 值2 值3 值4 值5 值1&#xff1a;水平阴影的位置值2&#xff1a;垂直阴影的位置值3&#xff1a;模糊距离值4&#xff1a;阴影的尺寸…

Spring篇--xml方式整合第三方框架

Spring xml方式整合第三方框架 xml整合第三方框架有两种整合方案&#xff1a; ​ 不需要自定义名空间&#xff0c;不需要使用Spring的配置文件配置第三方框架本身内容&#xff0c;例如&#xff1a;MyBatis&#xff1b; ​ 需要引入第三方框架命名空间&#xff0c;需要使用…

Javascript-web API-day02

文章目录 01-事件监听02-点击关闭广告03-随机点名案例04-鼠标经过或离开事件05-可点击的轮播图06-小米搜索框07-键盘类型事件08-键盘事件-发布评论案例09-focus选择器10-评论回车发布11-事件对象12-trim方法13-环境对象14-回调函数15-tab栏切换 01-事件监听 <!DOCTYPE html…

powershell(1)

免责声明 学习视频来自 B 站up主泷羽sec&#xff0c;如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识&#xff0c;以下代码、网站只涉及学习内容&#xff0c;其他的都与本人无关&#xff0c;切莫逾越法律红线&#xff0c;否则后果自负。 泷羽sec官网&#xff1a;http…

GraphReader: 将长文本结构化为图,并让 agent 自主探索,结合的大模型长文本处理增强方法

GraphReader: 将长文本结构化为图&#xff0c;并让 agent 自主探索&#xff0c;结合的大模型长文本处理增强方法 论文大纲理解为什么大模型和知识图谱不够&#xff1f;还要多智能体 设计思路数据分析解法拆解全流程核心模式提问为什么传统的长文本处理方法会随着文本长度增加而…

如何一站式计算抗体和蛋白信息

在生物医药研究领域&#xff0c;蛋白质&#xff08;抗体、多肽等&#xff09;的性质计算是理解生命机制、分离/纯化/鉴定/生产蛋白、以及开发蛋白新药的重要研究手段。然而&#xff0c;很多相关功能分散在不同的软件中&#xff0c;十分不方便。鹰谷电子实验记录本InELN一站式内…

物理信息神经网络(PINN)八课时教案

物理信息神经网络&#xff08;PINN&#xff09;八课时教案 第一课&#xff1a;物理信息神经网络概述 1.1 PINN的定义与背景 物理信息神经网络&#xff08;Physics-Informed Neural Networks&#xff0c;简称PINN&#xff09;是一种将物理定律融入神经网络训练过程中的先进方…

gitlab初始化+API批量操作

几年没接触gitlab了&#xff0c;新版本装完以后代码提交到默认的main分支&#xff0c;master不再是主分支 项目有几十个仓库&#xff0c;研发提交代码后仓库地址和之前的发生了变化 有几个点 需要注意 1、修改全局默认分支 2、关闭分支保护 上面修改了全局配置不会影响已经创…

【记录50】uniapp安装uview插件,样式引入失败分析及解决

SassError: Undefined variable: "$u-border-color". 表示样式变量$u-border-color没定义&#xff0c;实际是定义的 首先确保安装了scss/sass 其次&#xff0c;根目录下 app.vue中是否全局引入 <style lang"scss">import /uni_modules/uview-ui/in…

STM32CUBEMX+STM32H743ZIT6+MPU+DMA+UART下发指令对MPU配置管理

实现stm32H7的IAP过程&#xff0c;没有想象中的顺利。 需要解决串口DMA和MPU配置管理。 查看正点原子的MPU管理例程&#xff0c;想自己用串口下发指令&#xff0c;实现MPU打开&#xff0c;读取和写入指令。 中间遇到很多坑&#xff0c;比如串口DMA方式下发指令&#xff0c;没反…

8. 数组拼接

题目描述 现在有多组整数数组&#xff0c;需要将它们合并成一个新的数组。合并规则&#xff0c;从每个数组里按顺序取出固定长度的内容合并到新的数组中&#xff0c;取完的内容会删除掉&#xff0c;如果该行不足固定长度或者已经为空&#xff0c;则直接取出剩余部分的内容放到新…

Chrome 浏览器原生功能截长屏

我偶尔需要截取一些网页内容作为素材&#xff0c;但偶尔内容很长无法截全&#xff0c;需要多次截屏再拼接&#xff0c;过于麻烦。所以记录下这个通过浏览器原生功能截长屏的方案。 注意 这种方案并不是百分百完美&#xff0c;如果涉及到一些需要滚动加载的数据或者悬浮区块&am…

学技术学英文:代码中的锁:悲观锁和乐观锁

本文导读&#xff1a; 1. 举例说明加锁的场景&#xff1a; 多线程并发情况下有资源竞争的时候&#xff0c;如果不加锁&#xff0c;会出现数据错误&#xff0c;举例说明&#xff1a; 业务需求&#xff1a;账户余额>取款金额&#xff0c;才能取钱。 时间线 两人共有账户 …

深度学习之目标检测——RCNN

Selective Search 背景:事先不知道需要检测哪个类别,且候选目标存在层级关系与尺度关系 常规解决方法&#xff1a;穷举法&#xff0c;在原始图片上进行不同尺度不同大小的滑窗&#xff0c;获取每个可能的位置 弊端&#xff1a;计算量大&#xff0c;且尺度不能兼顾 Selective …

数字人在虚拟展厅中的应用方向有哪些?

数字人在虚拟展厅中的应用日益丰富&#xff0c;为参观者带来了前所未有的互动体验。以下是数字人在虚拟展厅中的几大主要应用方向&#xff1a; 1. 智能导览与讲解 在虚拟展厅中&#xff0c;数字人以其独特的魅力担任着导览员的角色。它们不仅为参观者提供精准的信息和指引&am…

WEB开发: 全栈工程师起步 - Python Flask +SQLite的管理系统实现

一、前言 罗马不是一天建成的。 每个全栈工程师都是从HELLO WORLD 起步的。 之前我们分别用NODE.JS 、ASP.NET Core 这两个框架实现过基于WebServer的全栈工程师入门教程。 今天我们用更简单的来实现&#xff1a; Python。 我们将用Python来实现一个学生管理应用&#xff0…

【我的 PWN 学习手札】IO_FILE 之 stdin任意地址写

我们知道&#xff0c;stdin会往“缓冲区”先读入数据&#xff0c;如果我们劫持这个所谓“缓冲区”到其他地址呢&#xff1f;是否可以读入数据到任意地址&#xff1f;答案是肯定的。 注意&#xff01;代码中的“-------”分隔&#xff0c;是为了区分一条调用链上不同代码片段&am…

从 Dify 到 Rill-Flow:大模型应用平台的进化之路

1. 基于 dify 的大模型应用平台构建 近些年&#xff0c;大语言模型领域的高速发展&#xff0c;涌现出了众多优秀的产品&#xff0c;能够解决很多实际的业务场景&#xff0c;大幅提升工作效率。各公司都纷纷搭建起了自己的大模型应用平台&#xff0c;来统一管理各种大语言模型&…