当前位置: 首页 > news >正文

JS中函数基础知识之查漏补缺(写给小白的学习笔记)

函数

函数是ECMAScript中 最有意思的部分之一, 主要是因为函数实际上是对象.-- 每个函数 都是Function类型的实例,Function也有属性和方法.

因为函数是对象,所以函数名就是指向函数对象的指针.

常用的定义函数的语法:

①函数声明 ②函数表达式 ③箭头函数

function sum (num1,num2) {return num1 + num2;
}
let sum = function( num1 ,sum2){return num1 + num2;
}
let sum = ( num1 , num2 ) => {return num1 + num2;
};

1. 箭头函数

ES6新增了 使用胖箭头 => 定义函数表达式的能力

任何可以使用函数表达式的地方, 都可以使用箭头函数.

箭头函数 简洁的语法 非常适合嵌入函数的场景

let ins = [1,2,3];
console.log( ins.map( function(i){ return i+1;} ) )//[2,3,4]
console.log( ins.map( (i) => { return i+1;} ) )//[2,3,4]

箭头函数的简写 : ① 如果只有一个参数, 那么参数部分的小括号可以省略 ②如果箭头后面只有一行代码,那么可以省略大括号{} 注意省略大括号 会隐式返回这行代码的值

箭头函数嵌入函数 以及它的简写形式: 

console.log( ins.map( (i) => { return i+1;} ) )//[2,3,4]
console.log( ins.map( i =>  i+1; ) )//[2,3,4]

箭头函数虽然语法简洁,但是很多场合不适用.

① 箭头函数不能使用 arguments对象 、super 和 new.target

② 箭头函数不能用作 构造函数

③ 此外 箭头函数也没有 prototype属性.

2. 函数名

因为函数名  就是指向函数的指针 存储的是该函数对象的引用地址.  所以他们和其他包含对象指针的变量 具有相同的行为. 这意味着一个函数可以有多个名称.如下所示

function sum(num1, num2) {return num1 + num2;
}console.log(sum(10, 10));  //20
let anotherSum = sum; //注意函数名后面没有小括号 只会访问函数指针 不会执行函数.
console.log(anotherSum(10, 10));  //20sum = null;  //sum 不再指向 函数的存储地址 但是函数对象还在
console.log(anotherSum(10, 10));  //20   //anotherSum 指向函数的存储地址 可以正常使用

3. 理解参数

ECMASript函数的参数 跟大多数其他语言不同, ECMASript函数既不关心 传入的参数的个数 也不关心这些参数的数据类型. 定义函数时 要接受两个参数,并不意味着调用函数时就传两个参数. 调用时 传 0个参数 1 个参数 3个参数 解释器都不会报错. 这是因为ECMAScript函数的参数在内部表现为一个数组. 函数被调用时 总会接收一个数组,但函数并不关心这个数组中包含什么.

事实上, 使用function关键字定义函数时(非箭头函数), 可以在函数内部访问arguments对象从中取得传进来的每个参数值.

arguments对象 是一个类数组对象,(但不是array的实例) ,因此可以使用中括号[] 访问其中的元素.(第一个参数是arguments[0] 第二个参数是arguments[1] ...) 要确定传进来多少个参数,可以访问arguments.length 属性.

function sayhi(name, message){console.log("hi "+name+","+message);
}
sayhi('Nico','新的一年 升职加薪 !!')
// 把函数重写为 不声明参数 函数还可以正常调用
function sayhello(){console.log("hello "+arguments[0]+","+arguments[1]);
}
sayhello('WanZi','新的一年 好运爆棚 !!')

arguments对象 可以跟命名参数一起使用. 如上方在函数 sayhi 中使用 arguments[0]和 name,并且 arguments对象的值 会和对应的命名参数值自动同步. 即修改 arguments[0]的值 name的值 也会随之改变, 反之亦然.

箭头函数中的参数

如果函数是使用 箭头语法定义的,那么传给函数的参数 将不能使用arguments关键字访问,只能通过定义的命名参数访问.

function foo () {console.log( arguments[0]);
}
foo(5); // 5let bar = () => {console.log( arguments[0] );
}
bar(5); //ReferenceError: arguments is not defined

虽然箭头函数没有arguments对象 但可以在包装函数中 把arguments 对象提供给 箭头函数。也就是外层函数使用function定义 所以有arguments对象 可以传递给该函数内部的箭头函数使用 这个arguments对象

function foo(){let bar = () =>{console.log( arguments[0]); }
bar();
}
foo(5);//5

注意 ECMAScript 中所有的参数都是按值进行传递的,变量调用时 参数存储的值 复制给 命名参数. 如果把对象作为参数传递,那么传递的值 就是这个对象的引用地址.(因为 该参数存储值 也只是对象的引用地址) (如下面代码与结果展示)

      let name = 'nico';function changeName(str){str = str +'happy';return str;}
// 函数调用 只是把参数name 存储的值 复制一份给到命名参数 strconsole.log(changeName(name));console.log(name);let obj = {a:1,b:2,}function change( o ){o.a +=10;o.b += 100;return o;}console.log(change(obj));console.log(obj);

命名参数O 和 变量obj 存储的值相同 即指向 同一个对象的引用地址. 所以change函数改变了对象内部的值 打印变量obj 结果也会随之改变.

4. 没有重载

java中一个函数可以有两个定义, 只要签名(接收参数的类型和数量)不同就行. ECMAScript函数不能像java等传统编程这样重载. 因为ECMAScript函数的参数是由包含 零个或多个值的数组表示.没有函数签名,也就没有重载.

如果在ECMAScript中定义了两个同名的函数 后定义的会覆盖先定义的. 函数变量名被重写 保存第二个函数对象的引用地址.

5. 默认参数值

在ES5及以前, 实现默认参数的一种常用方式 就是在函数内部检测某个参数 是否等于 undefined .如果是undefined就 意味着没有传这个参数 那就给它赋一个值.

在函数内部 name = ( typeof name !=='undefined' ) ? name : 'Henry'; 如果参数不是undefined那么 就等于它自己 否则就是默认值 'Henry'.

ES6之后, 支持显式定义默认参数. 只要在函数定义中的 参数后面用 = 就可以为参数赋一个默认值.

funtion( name = 'henry' , age =18 ){ }

注意 : 使用默认参数时, arguments对象的值 只反映 函数调用时传给函数的参数, 不会受参数默认值的影响. 修改命名参数也不会影响arguments对象.它始终以调用函数时传入的值为准.( 不使用默认参数值时 ,arguments对象会受 命名参数值的影响 与之同步改变 )

函数的默认参数 只有在函数被调用时 才会求值 不会在函数定义时求值.

箭头函数 同样可以使用默认参数值, 只是参数的 ( ) 不能被省略了let hi = (name='Henry' ) =>{ ... }

默认参数作用域与暂时性死区

因为在求值默认参数时 可以定义对象,也可以动态调用函数, 如 let hi = ( name=getName() ) =>{ ... } 所以函数参数肯定是在某个作用域中求值的.

给多个参数 定义默认值 实际上跟使用let关键字顺序声明变量一样. 默认参数会按照定义他们的顺序 依次被初始化. 因此 后定义默认值的参数 可以引用先定义的参数. 看下面例子所示

function makeKing ( name = 'Henry', numerals = name ) {return `King ${name} ${numerals}`; 
}
console.log( makeKing() ); //King Henry Henry//可以依照如下实例 想象一下这个过程
function makeKing () {let name = 'Henry';let numerals = namereturn `King ${name} ${numerals}`; 
}
console.log( makeKing() ); //King Henry Henry

参数初始化顺序 遵循"暂时性死区"规则, 即在参数定义前 ,不可以引用该参数.

function makeKing(name=numerals, numerals='VITT') {return `King ${name} ${numerals}`; 
}

如果调用上面的 makeMing函数 但是没有传第一参数 ,那么就会使用参数的默认值 numerals ,但是numerals变量还没有定义 所以这个时候会报错.

参数也存在于自己的作用域中,它们不能引用函数体的作用域:

function makeKing(name = 'Henry', numerals = defaultNumeral) {let defaultNumeral = 'VIII';return `King ${name} ${numerals}`;
}

上面代码中 makeKing函数调用时不传第二个参数会报错


6. 参数扩展与收集

ES6新增了 扩展操作符, 使用它可以非常简洁地 操作和组合 集合数据. 扩展操作符 最有用的场景就是函数定义中的参数列表. 在这里它可以充分利用JS的弱类型及参数长度可变的特点.

扩展操作符 即可以用于调用函数时 传参, 也可以用于定义 函数参数.

6.1. 扩展参数

给函数传参时, 有可能不需要传一个数组, 而是分别传入数组的元素.

在ES6中 可以使用扩展操作符,极为简洁地实现这种操作. 对可迭代对象 应用扩展操作符, 并将其作为一个参数传入 可以将可迭代对象拆分 并将迭代返回的每个值单独传入.

 let values = [1,2,3,4];function getSum(){let sum = 0;for(let i=0 ;i<arguments.length; i++){sum+= arguments[i];}return sum;}console.log( getSum(-1, ...values) )  //9console.log( getSum( ...values,5) )  //15console.log( getSum( ...values,5,...[2,3,4]) ) //24

对于函数中的 arguments而言,它并不知道 扩展操作符的存在,而是按照调用函数时 传入的参数接收每一个值.

arguments对象 只是消费扩展操作符的一种方式. 在普通函数(函数内部没有使用arguments对象)和箭头函数调用时 也可以将扩展操作符应用于命名参数. 这些函数在声明时也可以同时使用默认参数.

6.2. 收集参数

在函数定义时 可以使用扩展操作符. 那么在该函数调用时就可以 把不同长度的独立参数 组合为一个数组(例如下面例子中的values). 这有点类似arguments对象的构造机制 不过收集参数的结果会得到一个Array实例.

function getSum(...values){//初始值总和为0 顺序累加values中的所有值return values.reduce((x,y) => x+y, 0);
}
console.log(getSum(1,2,3) ) //6

收集参数的前面 如果还有命名参数,则只会收集其余的参数,如果没有其余的参数就会得到空数组. 因为收集参数的结果可以变,所以只把它作为最后一个参数, 否则就会报错 如下图所示

箭头函数虽然不支持 arguments对象 但是支持收集参数的定义方式,因此也可以实现 与使用arguments一样的逻辑.

使用收集参数 并不影响使用arguments对象 它依然反映调用时 传给函数的参数.

7. 函数声明与函数表达式

JS引擎在加载数据时, 对函数声明和函数表达式是区别对待的.

JS引擎 在任何代码执行之前 会先读取函数声明,并在执行上下文中 生成函数定义.   在执行代码时 JS引擎会先执行一遍扫描 把发现的函数声明提升到 源代码树的顶部. 因此函数声明可以出现在 调用该函数的代码之后. 这个过程叫做 函数声明提升.

函数表达式 必须等到代码执行到它那一行 才会在执行上下文中生成函数定义.

除了函数什么时候 真正有定义这个区别之外 这两种语法是等价的.

8. 函数作为值

因为函数名 在ECMASript中就是变量,所以函数可以用在任何可以使用变量的地方. 不仅可以把函数作为参数传给另一个函数, 还可以在一个函数名中返回另一个函数.要注意的是,如果是访问函数而不是调用函数,那就必须不带括号.

把函数作为参数传给另一个函数:

function callSomeFunction(someFunction, someArgument) {return someFunction(someArgument);
}

这个函数接收两个参数。第一个参数应该是一个函数,第二个参数应该是要传给这个函数的值。任

何函数都可以像下面这样作为参数传递:
function add10(num) {return num + 10;
}
let result1 = callSomeFunction(add10, 10);
console.log(result1); // 20
function getGreeting(name) {return "Hello, " + name;
}
let result2 = callSomeFunction(getGreeting, "Nicholas");
console.log(result2); // "Hello, Nicholas"

在一个函数名中返回另一个函数:

假设有一个包含对象的数组,而我们想按照任意对象属性对数组进行排序。为此,可以定义一个 sort()方法需要的比较函数,它接收两个参数,即要比较的值。但这个比较函数还需要想办法确定根据哪个属性来排序。这个问题可以通过 定义一个根据属性名来创建比较函数的函数来解决。比如:

function createComparisonFunction( propertyName ) {return function(object1, object2) {let value1 = object1[propertyName];let value2 = object2[propertyName];if (value1 < value2) {return -1;} else if (value1 > value2) {return 1;} else {return 0;}};
}
这个函数的语法乍一看比较复杂,但实际上就是在一个函数中返回另一个函数,注意那个 return
操作符。
内部函数可以访问 propertyName 参数,并通过中括号语法取得要比较的对象的相应属性值。
取得属性值以后,再按照 sort() 方法的需要 返回比较值就行了。这个函数可以像下面这样使用:
let data = [
{name: "Zachary", age: 28},
{name: "Nicholas", age: 29}
];
data.sort(createComparisonFunction("name"));
console.log(data[0].name); // Nichola

arr.sort 方法的使用: sort方法会对数组进行 原位(in-place) 排序,更改元素的顺序。(译注:原位是指在此数组内,而非生成一个新数组。)

要使用我们自己的排序顺序,我们需要提供一个函数作为 arr.sort() 的参数。

if (a > b) return 1; // 表示第一个值比第二个值大

if (a == b) return 0; // 表示两个值相等

if (a < b) return -1; // 表示第一个值比第二个值小

---------文章主要内容来自《JavaScript高级程序设计》-----------------------------------

相关文章:

JS中函数基础知识之查漏补缺(写给小白的学习笔记)

函数 函数是ECMAScript中 最有意思的部分之一, 主要是因为函数实际上是对象.-- 每个函数 都是Function类型的实例,Function也有属性和方法. 因为函数是对象,所以函数名就是指向函数对象的指针. 常用的定义函数的语法: ①函数声明 ②函数表达式 ③箭头函数 function sum (n…...

蓝桥杯训练

1对于一个字母矩阵&#xff0c;我们称矩阵中的一个递增序列是指在矩阵中找到两个字母&#xff0c;它们在同一行&#xff0c;同一列&#xff0c;或者在同一 45 度的斜线上&#xff0c;这两个字母从左向右看、或者从上向下看是递增的。 例如&#xff0c;如下矩阵中 LANN QIAO有…...

前端学习DAY33(外边距的折叠)

垂直外边距的重叠 在网页中相邻的垂直方向的外边距&#xff0c;会发生外边距的重叠 兄弟元素 兄弟元素之间的相邻外边距会取&#xff08;绝对值&#xff09;最大值&#xff0c;而不是取和&#xff0c;谁大取谁 特殊情况&#xff1a;如果相邻的外边距一正一负&#xff0c;则取两…...

asp.net core mvc的 ViewBag , ViewData , Module ,TempData

在 ASP.NET MVC 和 ASP.NET Core MVC 中&#xff0c;ViewBag 和 ViewData 是两种用于将数据从控制器传递到视图&#xff08;View&#xff09;的常用方法。它们都允许控制器将动态数据传递给视图&#xff0c;但它们的实现方式有所不同。关于 Module&#xff0c;它通常指的是某种…...

Linux驱动学习之第二个驱动程序(LED点亮关闭驱动程序-分层设计思想,使其能适应不同的板子-驱动程序模块为多个源文件怎么写Makefile)

目录 看这篇博文前请先掌握下面这些博文中的知识需要的PDF资料完整源代码board_fire_imx6ull-pro.c中的代码leddrv.c中的代码ledtest.c中的代码 程序设计思想和文件结构实现分层思想的具体方法概述具体实现分析定义结构体led_operations用来集合各个单板硬件层面操作LED的函数定…...

手写@EnableTransactionalManagement

定义一个注解&#xff0c;用于标注于方法上&#xff0c;标志着此方法是一个事务方法。 Target({ElementType.METHOD,ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) public interface MyTransaction {}定义一个开启事务功能的注解 Component Import(TransActionBean…...

【Vue】:解决动态更新 <video> 标签 src 属性后视频未刷新的问题

问题描述 在 Vue.js 项目&#xff0c;当尝试动态更新 <video> 标签的 <source> 元素 src 属性来切换视频时&#xff0c;遇到了一个问题&#xff1a;即使 src 属性已更改&#xff0c;浏览器仍显示旧视频。具体表现为用户选择新视频后&#xff0c;视频区域继续显示之…...

网络基础1 http1.0 1.1 http/2的演进史

http1.0 1.1 http/2的演进史&#x1f60e; &#xff08;连接复用 队头阻塞 服务器推送 2进制分帧&#xff09; 概述 我们主要关注的是应用层 传输层 http协议发展历史 http的报文结构&#xff1a;起始行 Header Body http的典型特征 http存在的典型问题 Keep Alive机制 chun…...

Python 通过命令行在 unittest.TestCase 中运行单元测试

文章目录 unittest 模块简介编写单元测试在命令行中运行所有测试在命令行中运行单个测试使用装饰器跳过测试总结常用断言方法 unittest 模块简介 unittest是Python标准库中的一个模块&#xff0c;用于编写和运行单元测试。它提供了一个单元测试框架&#xff0c;使得编写测试用…...

源代码编译安装X11及相关库、vim,配置vim(2)

一、编译安装vim 编译时的cofigure选项如下.只有上一步的X11的包安装全了&#xff08;具体哪些是必须的&#xff0c;哪些是多余的没验证&#xff09;&#xff0c;configure才能认为X的库文件和头文件是可以用的。打开多个编程语言的支持特性。 ./configure --prefixpwd/mybui…...

设计模式 行为型 观察者模式(Observer Pattern)与 常见技术框架应用 解析

观察者模式&#xff08;Observer Pattern&#xff09;是一种行为设计模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时&#xff0c;会通知所有观察者对象&#xff0c;使它们能够自动更新。 一…...

【25考研】川大计算机复试情况,重点是啥?怎么准备?

24年进入复试的同学中&#xff0c;有10位同学的复试成绩为0分。具体是个人原因还是校方原因&#xff0c;还尚不明确。但是C哥提醒&#xff0c;一定要认真复习&#xff01;复试完后不要跟任何人讨论有关复试的题目及细节&#xff01; 一、复试内容 四川大学复试内容较多&#xf…...

C#调用Lua

目录 xLua导入 打包工具导入 单例基类导入与AB包管理器导入 Lua解析器 文件加载与重定向 Lua解析器管理器 全局变量获取 全局函数获取 对于无参数无返回值 对于有参数有返回值 对于多返回值 对于变长参数 完整代码 List与Dictionary映射Table 类映射Table 接口映射…...

LeetCode100之组合总和(39)--Java

1.问题描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复…...

NTN学习笔记之术语和缩写词解析

去发现&#xff0c;去努力&#xff0c;去表达。 参考&#xff1a;3GPP TR 38.811&#xff08;R15&#xff09;&#xff0c;TR 38.821&#xff08;R16&#xff09; 目录 0. NTN典型架构图1. 术语2. 缩写 0. NTN典型架构图 为了方便对术语场景的理解&#xff0c;先放上两张NTN典…...

Yolo11改进:注意力改进|Block改进|ESSAformer,用于高光谱图像超分辨率的高效Transformer|即插即用

摘要 一、论文介绍 高光谱图像超分辨率的重要性:高光谱成像技术通过密集采样光谱特征,为材料区分提供丰富的光谱和空间结构信息,广泛应用于各领域。高光谱图像超分辨率(HSI-SR)旨在从低分辨率HSI生成高分辨率HSI。传统方法的局限性:传统方法依赖手工制作的先验,如低秩近…...

STM32 单片机 练习项目 LED灯闪烁LED流水灯蜂鸣器 未完待续

个人学习笔记 文件路径&#xff1a;程序源码\STM32Project-DAP&DAPmini\1-1 接线图 3-1LED闪烁图片 新建项目 新建项目文件 选择F103C8芯片 关闭弹出窗口 拷贝资料 在项目内新建3个文件夹 Start、Library、User Start文件拷贝 从资料中拷贝文件 文件路径&#xff1a;固…...

使用PyTorch实现基于稀疏编码的生成对抗网络(GAN)在CIFAR-10数据集上的应用

使用PyTorch实现基于稀疏编码的生成对抗网络(GAN)在CIFAR-10数据集上的应用 目录 使用PyTorch实现基于稀疏编码的生成对抗网络(GAN)在CIFAR-10数据集上的应用1. 引言2. 数据集介绍3. 模型网络结构3.1 网络结构3.2 编码器3.3 生成器3.4 判别器4. 模型优化器与损失函数4.1 优…...

用matlab调用realterm一次性发送16进制数

realterm采用PutString接口进行发送&#xff0c;需要注意的是发送的16进制数前面要加入0x标志。只有这样&#xff0c;realterm才能将输入的字符串识别为16进制数的形式。 另外,PutString函数支持两个参数输入&#xff0c;第一个参数为字符串&#xff0c;第二个参数为发送形式&…...

通过可穿戴外骨骼,以更灵活的方式操作你的机器人。

今天&#xff0c;我们将介绍一款专为控制 Mercury X1 和 Mercury B1 机械臂而设计的创新外骨骼。这种外骨骼以人类手臂的结构为蓝本&#xff0c;可实现直观和精确的控制。 开发这种外骨骼的动机源于人们对深度学习和机器学习等领域日益增长的兴趣。这些技术使机器人能够自主学习…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

Bean 作用域有哪些?如何答出技术深度?

导语&#xff1a; Spring 面试绕不开 Bean 的作用域问题&#xff0c;这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开&#xff0c;结合典型面试题及实战场景&#xff0c;帮你厘清重点&#xff0c;打破模板式回答&#xff0c…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言&#xff1a;生成式AI的黎明 – Diffusion模型是什么&#xff1f; 近年来&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;领域取得了爆炸性的进展&#xff0c;模型能够根据简单的文本提示创作出逼真的图像、连贯的文本&#xff0c;乃至更多令人惊叹的…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...

大数据驱动企业决策智能化的路径与实践

&#x1f4dd;个人主页&#x1f339;&#xff1a;慌ZHANG-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、引言&#xff1a;数据驱动的企业竞争力重构 在这个瞬息万变的商业时代&#xff0c;“快者胜”的竞争逻辑愈发明显。企业如何在复杂环…...