函数与函数式编程
转自:微点阅读 https://www.weidianyuedu.com/content/4317415636514.html
纵观JavaScript中所有必须需要掌握的重点知识中,函数是我们在初学时最容易忽视的知识点。可能会有很多人、很多文章告诉你面向对象很重要,原型很重要,可是却很少有人告诉你,面向对象中所有的重点难点,几乎都与函数息息相关。
包括我之前几篇文章介绍的执行上下文,变量对象,闭包,this等,都是围绕函数的细节来展开。
很多人在学习中,很急切的希望自己快一点开始学习面向对象,学习模块,学习流行框架,迅速成为高手。但是我可以很负责的告诉你,关于函数的这些基础东西没理解到一定程度,那么你的学习进展一定是举步维艰的。
所以,大家一定要重视函数!
当然,关于函数的重点,难点在前面几篇文章都已经说得差不多了,这篇文章主要总结一下函数的基础知识,并初步学习函数式编程的思维。
一、函数声明、函数表达式、匿名函数与自执行函数
关于函数在实际开发中的应用,大体可以总结为函数声明、函数表达式、匿名函数、自执行函数。
函数声明
JavaScript中,有两种声明方式,一个是使用var/let/const
的变量声明,另一个是使用function
的函数声明。
在前端基础进阶(三):变量对象详解[1]中我有提到过,变量对象的创建过程中,函数声明比变量声明具有更为优先的执行顺序,即我们常常提到的函数声明提前。因此我们在执行上下文中,无论在什么位置声明了函数,都可以在同一个执行上下文中直接使用该函数。
fn(); // function
function fn() {
console.log("function");
}
函数表达式
与函数声明不同,函数表达式使用了var/let/const进行声明,那么我们在确认他是否可以正确使用的时候就必须依照var/let/const的规则进行判断,即变量声明。我们知道使用var进行变量声明,其实是进行了两步操作。
// 变量声明
var a = 20;
// 实际执行顺序
var a = undefined; // 变量声明,初始值undefined,变量提升,提升顺序次于function声明
a = 20; // 变量赋值,该操作不会提升
同样的道理,当我们使用变量声明的方式来声明函数时,就是我们常常说的函数表达式。函数表达的提升方式与变量声明一致。
fn(); // 报错
var fn = function() {
console.log("function");
}
上例子的执行顺序为:
var fn = undefined; // 变量声明提升
fn(); // 执行报错
fn = function() { // 赋值操作,此时将后边函数的引用赋值给fn
console.log("function");
}
由于声明方式的不同,导致了函数声明与函数表达式在使用上的一些差异需要我们注意,除此之外,这两种形式的函数在使用上并无不同。
关于上面例子,函数表达式中的赋值操作,在其他一些地方也会被经常使用,我们清楚其中的关系即可。
// 在构造函数中添加方法
function Person(name) {
this.name = name;
this.age = age;
// 在构造函数内部中添加方法
this.getAge = function() {
return this.age;
}
this.
}
// 给原型添加方法
Person.prototype.getName = function() {
return this.name;
}
// 在对象中添加方法
var a = {
m: 20,
getM: function() {
return this.m;
}
}
匿名函数
匿名函数,顾名思义,就是指的没有被显示进行赋值操作的函数。它的使用场景,多作为一个参数传入另一个函数中。
var a = 10;
var fn = function(bar, num) {
return bar() + num;
}
fn(function() {
return a;
}, 20)
在上面的例子中,fn的第一个参数传入了一个匿名函数。虽然该匿名函数没有显示的进行赋值操作,我们没有办法在外部执行上下文中引用到它,但是在fn函数内部,我们将该匿名函数赋值给了变量bar,保存在了fn变量对象的arguments对象中。
// 变量对象在fn上下文执行过程中的创建阶段
VO(fn) = {
arguments: {
bar: undefined,
num: undefined,
length: 2
}
}
// 变量对象在fn上下文执行过程中的执行阶段
// 变量对象变为活动对象,并完成赋值操作与执行可执行代码
VO -> AO
AO(fn) = {
arguments: {
bar: function() { return a },
num: 20,
length: 2
}
}
由于匿名函数传入另一个函数之后,最终会在另一个函数中执行,因此我们也常常称这个匿名函数为回调函数。关于匿名函数更多的内容,我会在下一篇深入探讨柯里化的文章中进行更加详细讲解。
匿名函数的这个应用场景几乎承担了函数的所有难以理解的知识点,因此我们一定要对它的这些细节了解的足够清楚,如果对于变量对象的演变过程你还看不太明白,一定要回过头去看这篇文章:前端基础进阶(三):变量对象详解[2]
函数自执行与块级作用域
在ES5中,没有块级作用域,因此我们常常使用函数自执行的方式来模仿块级作用域,这样就提供了一个独立的执行上下文,结合闭包,就为模块化提供了基础。而函数自执行,其实是匿名函数的一种应用。
(function() {
// ...
})();
一个模块往往可以包括:私有变量、私有方法、公有变量、公有方法。
根据作用域链的单向访问,外面可能很容易知道在这个独立的模块中,外部执行环境是无法访问内部的任何变量与方法的,因此我们可以很容易的创建属于这个模块的私有变量与私有方法。
(function() {
// 私有变量
var age = 20;
var name = "Tom";
// 私有方法
function getName() {
return `your name is ` + name;
}
})();
但是共有方法和变量应该怎么办?大家还记得我们前面讲到过的闭包的特性吗?没错,利用闭包,我们可以访问到执行上下文内部的变量和方法,因此,只需要根据闭包的定义,创建一个闭包,将你认为需要公开的变量和方法开放出来即可。
(function() {
// 私有变量
var age = 20;
var name = "Tom";
// 私有方法
function getName() {
return `your name is ` + name;
}
// 共有方法
function getAge() {
return age;
}
// 将引用保存在外部执行环境的变量中,形成闭包,防止该执行环境被垃圾回收
window.getAge = getAge;
})();
当然,闭包在模块中的重要作用,我们在讲解闭包的时候已经强调过,但是这个知识点真的太重要,需要我们反复理解并且彻底掌握。
为了帮助大家进一步理解闭包,我们来看看jQuery中,是如何利用模块与闭包的。
// 使用函数自执行的方式创建模块
(function(window, undefined) {
// 声明jQuery构造函数
var jQuery = function(name) {
// 主动在构造函数中,返回一个jQuery实例
return new jQuery.fn.init(name);
}
// 添加原型方法
jQuery.prototype = jQuery.fn = {
constructor: jQuery,
init:function() { ... },
css: function() { ... }
}
jQuery.fn.init.prototype = jQuery.fn;
// 将jQuery改名为$,并将引用保存在window上,形成闭包,对外开放jQuery构造函数,这样我们就可以访问所有挂载在jQuery原型上的方法了
window.jQuery = window.$ = jQuery;
})(window);
// 在使用时,直接执行了构造函数,因为在jQuery的构造函数中通过一些手段,返回的是jQuery的实例,所以我们就不用再每次用的时候自己new一个实例
$("#div1");
在这里,我们只需看懂闭包与模块的部分就行,至于内部的原型链是如何绕的,为什么会这样写,在讲面向对象的时候会为大家慢慢分析。举这个例子的目的所在,就是希望大家能够重视函数,在实际开发中,它无处不在。
接下来我要分享一个高级的,非常有用的模块的应用。当我们的项目越来越大,那么需要保存的数据与状态就越来越多,因此,我们需要一个专门的模块来维护这些数据,这个时候,一个叫做状态管理器的东西就应运而生。对于状态管理器,最出名的,我想非redux莫属了。虽然对于还在学习中的大家来说,redux是一个有点高深莫测的东西,但是在我们学习之前,可以先通过简单的方式,让大家大致了解状态管理器的实现原理,为我们未来的学习奠定坚实的基础。
先来直接看代码。
// 自执行创建模块
(function() {
// states 结构预览
// states = {
// a: 1,
// b: 2,
// m: 30,
// o: {}
// }
var states = {}; // 私有变量,用来存储状态与数据
// 判断数据类型
function type(elem) {
if(elem == null) {
return elem + "";
}
return toString.call(elem).replace(/[\[\]]/g, "").split(" ")[1].toLowerCase();
}
/**
* @Param name 属性名
* @Description 通过属性名获取保存在states中的值
*/
function get(name) {
return states[name] ? states[name] : "";
}
function getStates() {
return states;
}
/*
* @param options {object} 键值对
* @param target {object} 属性值为对象的属性,只在函数实现时递归中传入
* @desc 通过传入键值对的方式修改state树,使用方式与小程序的data或者react中的setStates类似
*/
function set(options, target) {
var keys = Object.keys(options);
var o = target ? target : states;
keys.map(function(item) {
if(typeof o[item] == "undefined") {
o[item] = options[item];
}
else {
type(o[item]) == "object" ? set(options[item], o[item]) : o[item] = options[item];
}
return item;
})
}
// 对外提供接口
window.get = get;
window.set = set;
window.getStates = getStates;
})()
// 具体使用如下
set({ a: 20 }); // 保存 属性a
set({ b: 100 }); // 保存属性b
set({ c: 10 }); // 保存属性c
// 保存属性o, 它的值为一个对象
set({
o: {
m: 10,
n: 20
}
})
// 修改对象o 的m值
set({
o: {
m: 1000
}
})
// 给对象o中增加一个c属性
set({
o: {
c: 100
}
})
console.log(getStates())
demo实例在线地址[3]
我之所以说这是一个高级应用,是因为在单页应用中,我们很可能会用到这样的思路。根据我们提到过的知识,理解这个例子其实很简单,其中的难点估计就在于set方法的处理上,为了具有更多的适用性,做了很多适配,用到了递归等知识。如果你暂时看不懂,没有关系,知道如何使用就行,上面的代码可以直接运用于实践开发。记住,当你需要保存的状态太多的时候,你想到这一段代码就行。
函数自执行的方式另外还有其他几种写法,诸如
!function(){}()
,+function(){}()
二、函数参数传递方式:按值传递
还记得基本数据类型与引用数据类型在复制上的差异吗?基本数据类型复制,是值直接发生了复制,因此改变后,各自相互不影响。但是引用数据类型的复制,是保存在变量对象中的引用发生了复制,因此复制之后的这两个引用实际访问的实际是同一个堆内存中的值。当改变其中一个时,另外一个自然也被改变。如下例。
var a = 20;
var b = a;
b = 10;
console.log(a); // 20
var m = { a: 1, b: 2 }
var n = m;
n.a = 5;
console.log(m.a) // 5
当值作为函数的参数传递进入函数内部时,也有同样的差异。我们知道,函数的参数在进入函数后,实际是被保存在了函数的变量对象中,因此,这个时候相当于发生了一次复制。如下例。
var a = 20;
function fn(a) {
a = a + 10;
return a;
}
fn(a);
console.log(a); // 20
var a = { m: 10, n: 20 }
function fn(a) {
a.m = 20;
return a;
}
fn(a);
console.log(a); // { m: 20, n: 20 }
正是由于这样的不同,导致了许多人在理解函数参数的传递方式时,就有许多困惑。到底是按值传递还是按引用传递?实际上结论仍然是按值传递,只不过当我们期望传递一个引用类型时,真正传递的,只是这个引用类型保存在变量对象中的引用而已。为了说明这个问题,我们看看下面这个例子。
var person = {
name: "Nicholas",
age: 20
}
function setName(obj) { // 传入一个引用
obj = {}; // 将传入的引用指向另外的值
obj.name = "Greg"; // 修改引用的name属性
}
setName(person);
console.log(person.name); // Nicholas 未被改变
在上面的例子中,如果person是按引用传递,那么person就会自动被修改为指向其name属性值为Gerg的新对象。但是我们从结果中看到,person对象并未发生任何改变,因此只是在函数内部引用被修改而已。
四、函数式编程
虽然JavaScript并不是一门纯函数式编程的语言,但是它使用了许多函数式编程的特性。因此了解这些特性可以让我们更加了解自己写的代码。
当我们想要使用一个函数时,通常情况下其实就是想要将一些功能,逻辑等封装起来。相信大家对于封装这个概念并不陌生。
我们通常通过函数封装来完成一件事情。例如,想要计算任意三个数的和,我们就可以将这三个数作为参数,封装一个简单的函数。
function add(a, b, c) {
return a + b + c;
}
当我们想要计算三个数的和时,直接调用该方法即可。
add(1, 2, 3); // 6
当然,当想要做的事情比较简单时,可能还看不出来封装成为函数之后带来的便利。如果我们想要做的事情稍微复杂一点呢。例如我想要计算一个数组中的所有子项目的和。
function mergeArr(arr) {
var result = 0;
for(var i = 0; i < arr.length; i++) { result += arr[i] }
return result;
}
如果不通过函数封装的方式,那么再每次想要实现这个功能时,就不得不重新使用一次for循环,这样的后果就是我们的代码中充斥着越来越多的重复代码。而封装之后,当我们想要再次做这件事情的时候,只需要一句话就可以了。
mergeArr([1, 2, 3, 4, 5]);
当然,我相信大家对于函数封装的意义都应该有非常明确的认知,但是我们要面临的问题是,当我们想要去封装一个函数时,如何做才是最佳实践呢?
函数式编程能给我们答案。
我们在初学时,往往会不由自主的使用命令式编程的风格来完成我们想要干的事情。因为命令式编程更加的简单,直白。例如我们现在有一个数组,array = [1, 3, "h", 5, "m", "4"]
,现在想要找出这个数组中的所有类型为number的子项。当我们使用命令式编程思维时,可能就会直接这样做。
var array = [1, 3, "h", 5, "m", "4"];
var res = [];
for(var i = 0; i < array.length; i ++) {
if (typeof array[i] === "number") {
res.push(array[i]);
}
}
在这种实现方式中,我们平铺直叙的实现了我们的目的。这样做的问题在于,当我们在另外的时刻,想要找出另外一个数组中所有的子项时,我们不得不把同样的逻辑再写一次。当出现次数变多时,我们的代码也变得更加糟糕且难以维护。
而函数式编程的思维则建议我们将这种会多次出现的功能封装起来以备调用。
function getNumbers(array) {
var res = [];
array.forEach(function(item) {
if (typeof item === "number") {
res.push(item);
}
})
return res;
}
// 以上是我们的封装,以下是功能实现
var array = [1, 3, "h", 5, "m", "4"];
var res = getNumbers(array);
将功能封装之后,我们实现同样的功能时,只需要写一行代码。而如果未来需求变动,或者稍作修改,我们只需要对getNumbers方法进行调整就可以了。而且我们在使用时,只需要关心这个方法能做什么,而不用关心他具体是怎么实现的。这也是函数式编程思维与命令式不同的地方之一。
函数式编程思维还具有以下几个特征。
函数是第一等公民
所谓"第一等公民"(first class),指的是函数与其他数据类型一样,处于平等地位,可以赋值给其他变量,也可以作为参数,传入另一个函数,或者作为别的函数的返回值。这些场景,我们应该见过很多。
var a = function foo() {} // 赋值
function fn(function() {}, num) {} // 函数作为参数
// 函数作为返回值
function var() {
return function() {
... ...
}
}
当然,这都是JavaScript的基本概念。但是我想很多人,甚至包括正在阅读的你自己都可能会无视这些概念。可以用一个简单的例子来验证一下。
我们先自定义这样一个函数。
function delay() {
console.log("5000ms之后执行该方法.");
}
现在要做的是,如果要求你结合setTimeout方法,让delay方法延迟5000ms执行,应该怎么做?
其实很简单,对不对,直接这样就可以了。
var timer = setTimeout(function() {
delay();
}, 5000);
那么现在问题来了,如果你对函数是一等公民有一个深刻的认知,我想你会发现上面这种写法其实是有一些问题的。所以思考一下,问题出在哪里?
函数既然能够作为一个参数传入另外一个函数,那么我们是不是可以直接将delay作为setTimeout的第一个参数,而不用额外的多加一层匿名函数呢?
因此,其实最正确的解法应该这样写。
var timer = setTimeout(delay, 5000);
当然,如果你已经提前想到这样做了,那么恭喜你,说明你在JavaScript上比普通人更有天赋。其实第一种糟糕的方式很多人都在用,包括有多年工作经验的人也没有完全避免。而他们甚至还不知道自己问题出在什么地方。
在未来的实践中,你还会遇到更多类似的场景。为了验证读者朋友们的理解,我们不妨来思考一下如何优化下面的代码。
function getUser(path, callback) {
return $.get(path, function(info) {
return callback(info);
})
}
getUser("/api/user", function(resp) {
// resp为成功请求之后返回的数据
console.log(resp);
})
优化的原理和setTimeout的例子一模一样,我这里卖个关子,不打算告诉大家结论,仅提示一句,getUser优化之后,仅有一句代码。考验大家学习成果的时候到了 ^ ^。
只用"表达式",不用"语句"
"表达式"(expression)是一个单纯的运算过程,总是有返回值;"语句"(statement)是执行某种操作,没有返回值。函数式编程要求,只使用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。
假如我们的项目中,多处需要改变某个元素的背景色。因此我们可以这样封装一下。
var ele = document.querySelector(".test");
function setBackgroundColor(color) {
ele.style.backgroundColor = color;
}
// 多处使用
setBackgroundColor("red");
setBackgroundColor("#ccc");
我们可以很明显的感受到,setBackgroundColor封装的仅仅只是一条语句。这并不是理想的效果。函数式编程期望一个函数有输入,也有输出。因此良好的习惯应该如下做。
function setBackgroundColor(ele, color) {
ele.style.backgroundColor = color;
return color;
}
// 多处使用
var ele = document.querySelector(".test");
setBackgroundColor(ele, "red");
setBackgroundColor(ele, "#ccc");
了解这一点,可以让我们自己在封装函数的时候养成良好的习惯。
纯函数
相同的输入总会得到相同的输出,并且不会产生副作用的函数,就是纯函数。
所谓"副作用"(side effect),指的是函数内部与外部互动(最典型的情况,就是修改全局变量的值),产生运算以外的其他结果。
函数式编程强调没有"副作用",意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。
即:只要是同样的参数传入,返回的结果一定是相等的。
例如我们期望封装一个函数,能够得到传入数组的最后一项。那么可以通过下面两种方式来实现。
function getLast(arr) {
return arr[arr.length];
}
function getLast_(arr) {
return arr.pop();
}
var source = [1, 2, 3, 4];
var last = getLast(source); // 返回结果4 原数组不变
var last_ = getLast_(source); // 返回结果4 原数据最后一项被删除
getLast与getLast_虽然同样能够获得数组的最后一项值,但是getLast_改变了原数组。而当原始数组被改变,那么当我们再次调用该方法时,得到的结果就会变得不一样。这样不可预测的封装方式,在我们看来是非常糟糕的。它会把我们的数据搞得非常混乱。在JavaScript原生支持的数据方法中,也有许多不纯的方法,我们在使用时需要非常警惕,我们要清晰的知道原始数据的改变是否会留下隐患。
var source = [1, 2, 3, 4, 5];
source.slice(1, 3); // 纯函数 返回[2, 3] source不变
source.splice(1, 3); // 不纯的 返回[2, 3, 4] source被改变
source.pop(); // 不纯的
source.push(6); // 不纯的
source.shift(); // 不纯的
source.unshift(1); // 不纯的
source.reverse(); // 不纯的
// 我也不能短时间知道现在source被改变成了什么样子,干脆重新约定一下
source = [1, 2, 3, 4, 5];
source.concat([6, 7]); // 纯函数 返回[1, 2, 3, 4, 5, 6, 7] source不变
source.join("-"); // 纯函数 返回1-2-3-4-5 source不变
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- 数据结构-第三章-栈和队列(4)-循环队列
数据结构 ⚡️数据结构-第一章 ⚡️抽象数据类型案例 ⚡️数据结构-第二章(1)-线性结构 ⚡️数据结构-第二章(2)-线性表的顺序表示和实现 ⚡️数据结构-第二章(3)-顺序表(含代码) ⚡…...
2024/4/14 9:10:27 - 八、Spring Boot thymeleaf 常用语法
八、Spring Boot thymeleaf 常用语法(一)、字符串输出1. th:text2. th:value3.字符串操作(二)、日期操作1. 日期格式化2.日期提取(三)、条件判断1.th:if2.th:switch(四)、迭代(一&am…...
2024/4/14 9:10:12 - Mybatis(2 ResultType和ResultMap)
ResultType 类型别名是你的好帮手。使用它们,你就可以不用输入类的全限定名了。比如: <!-- mybatis-config.xml 中 --> <!--别名--> <typeAliases><typeAlias type"com.xxx.po.UserInfo" alias"UserInfo"/&g…...
2024/4/15 13:22:09 - 0基础也能编程井字棋?教程来了
1.制作框架 2.利用函数以及循环完成井字棋的编程 3.开始和呆呆的机器人下棋吧 //game.h #define row 3 #define col 3 #include<stdlib.h>; #include<time.h> #include<Windows.h> void qpcsh(char arr[row][col], int a, int b); void qpprint(char arr…...
2024/4/19 18:20:54 - L3-012 水果忍者
题目: 2010年风靡全球的“水果忍者”游戏,想必大家肯定都玩过吧?(没玩过也没关系啦~)在游戏当中,画面里会随机地弹射出一系列的水果与炸弹,玩家尽可能砍掉所有的水果而避免砍中炸弹,…...
2024/4/14 9:10:22 - 001-LED灯
**树莓派科学小实验 LTE灯 —001 点亮第一盏LED灯 目录前言一、查询管脚定义前言 本次开始将在上一章中的实验板上做实验 提示:以下是本篇文章正文内容,下面案例可供参考 一、查询管脚定义 查询商家给出的定义, 可以看到LED-红 接在了BCM…...
2024/4/14 9:10:32 - 纪念:中国-东盟数字创新大赛(人工智能赛道)决赛第十名
...
2024/5/7 5:30:38 - 《剑指Offer》学习记录—算法题:数组中的重复数字
题目 找出数组中重复的数字。 在一个长度为 n 的数组里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。 示例 输入: [2, 3, 1, …...
2024/4/14 9:10:17 - 本地调用服务器Docker
一 服务器配置 1.查看docker.service文件位置systemctl status docker 2.修改docker.service文件 vi /etc/xx/xx/docker.service 在 ExecStart/usr/bin/dockerd 后面加上 -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock 3.重启docker服务 重载service文件 systemctl …...
2024/4/22 5:26:54 - React 的基本使用 (单页面以及有关jsx的面试题,语法规范)
React 的基本使用! React 介绍! React 是一个用于构建用户界面的 JAVASCRIPT 库。 React 主要用于构建 UI,很多人认为 React 是 MVC 中的 V(视图)。 React 起源于 Facebook 的内部项目,用来架设 Instagram…...
2024/4/29 16:12:14 - 我的无影云电脑初体验
一、背景 最近看到阿里云开发者社区有无影云电脑的体验活动,遂报名体验。 由于在阿里云开发者社区是专家博主,有幸获得一年的 4核 8G 无影云电脑的体验机会。 试用了几天,下面从无影云电脑的用户群体、无影云电脑的使用场景,我的…...
2024/4/15 13:22:24 - Java集合经典26问
今天给大家分享 Java集合常考的面试题 ,准备找工作的小伙伴赶紧收藏起来~ 常见的集合有哪些? Java集合类主要由两个接口 Collection 和 Map 派生出来的,Collection有三个子接口:List、Set、Queue。 Java集合框架图如下…...
2024/4/14 9:10:12 - SQL之DDL创建小案例
需求:设计学生表,注意数据类型、长度合理性 编号姓名,性别,生日,年月日入学成绩,小数点后两位邮件地址,最大长度不超64家庭联系电话,不一定手机号码,可能有-字符学生状态…...
2024/4/26 16:43:53 - C++STL总结
(一)STL概述 1.什么是STL? 标准模板类(Standard Template Library) 2.STL主要由几部分组成? 算法、容器、迭代器 3.STL主要用了什么技术实现? 模板技术 4.如何宣称与使用名空间,如何…...
2024/4/14 9:10:37 - Unity 柏林噪声
关于柏林噪声: 先粘贴关于百度百科的一段话: 柏林噪声 (Perlin noise )指由Ken Perlin发明的自然噪声生成算法 。一个噪声函数基本上是一个种子随机发生器。它需要一个整数作为参数,然后根据这个参数返回一个随机数。如果两次都传同一个参数…...
2024/4/14 9:10:37 - 你真的了解反射吗?
1. 啥是反射 1.初识反射 刚开始学反射的时候,我是一脸懵逼的,这玩意真的是“抽象的妈妈给抽象开门-抽象到家了。” 为什么创建对象要先获取 Class 对象?这不多此一举吗?我直接 new 一下不是更简单吗? 什么是程序运…...
2024/4/15 13:22:49 - Rstudio Server 不同R版本配置和切换
版本兼容性问题一直是生信初学者最容易掉进去的大坑。 Rstudio的香,用过的人都知道。 Rstudio Desktop for Windows/Mac 切换不同R版本非常简单,Tools→Global Options→General→Basic→R Sessions→R version→Change: 服务器上Rstudio Server之前配置的R3.6有可能不太符…...
2024/4/14 9:11:08 - 2021年秋季《交换机路由器配置(省)》04交换机路由器配置
2021年秋季《交换机路由器配置(省)》04交换机路由器配置 1.[单选题] FTP数据连接端口号( )。 A.20 B.21 C.23 D.25 答:——A—— 2.[单选题] 下列关于路由的描述中,哪一项较为接近静态路由的定义( )。 A.明确了目的地网络地址,但不…...
2024/4/15 17:08:48 - 恐怖的Bug记录
恐怖的Bug记录 这是一个结合\文件读取和保存\套接字 TCP \多线程 的一个编程 预期: 照片被读取为字节形式,然后打包为udp包 ,发送到接收端,接收端保存。 保存的时候自动创建文件,文件名递增,保证不重复…...
2024/4/15 21:44:13 - 基于BearPi套件开发的智能儿童手表系统
一、 介绍 本项目是基于BearPi套件开发的智能儿童手表系统,该系统通过与GSM模块(型号:SIM808)的通信来实现通话和定位功能。 智能儿童手表系统可以通过云和手机建立连接,同步时间和获取天气信息,通过手机下…...
2024/4/7 15:45:55
最新文章
- Linux--IIC驱动编程实验
对于 I2C 主机驱动,一旦编写完成就不需要再做修改,其他的 I2C 设备直接调用主机驱动提供的 API 函数完成读写操作即可。这个正好符合 Linux 的驱动分离与分层的思想,因此 Linux内核也将 I2C 驱动分为两部分: ①、 I2C 总…...
2024/5/7 5:35:37 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/5/6 9:38:23 - 解决npm install安装node-sass包容易失败的问题
具体问题如下: npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: XXX3.4.0 npm ERR! Found: webpack5.31.2 npm ERR! node_modules/webpack npm ERR! peer webpack”^4.0.0 || ^5.0.0″ from html-…...
2024/5/6 13:31:08 - audio_video_img图片音视频异步可视化加载
最近在做即时消息,消息类型除了文字还有音频、视频、图片展示,如果消息很多,在切换聊天框时,会有明显卡顿,后续做了懒加载,方案是只加载用户能看到的资源,看不到的先不加载; LazyAud…...
2024/5/6 12:26:53 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/5/4 23:54:56 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/5/4 23:54:56 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/5/4 23:54:56 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/5/6 9:21:00 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/5/4 23:54:56 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/5/4 23:55:05 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/5/4 23:54:56 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/5/4 23:55:16 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/5/4 23:54:56 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/5/6 1:40:42 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/5/4 23:54:56 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/5/4 23:55:17 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/5/4 23:55:06 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/5/4 23:54:56 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/5/4 23:55:06 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/5/5 8:13:33 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/5/4 23:55:16 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/5/4 23:54:58 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/5/6 21:42:42 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/5/4 23:54:56 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57