么是函数?
把一段相对独立的具有特定功能的代码块封装起来,形成一个独立实体,就是函数,起个名字(函数名),在后续开发中可以反复调用。函数的作用就是封装一段代码,将来可以重复使用。推荐了解黑马程序员web前端课程。
为什么要使用函数?为了解决代码的重用!减少代码量。
函数的分类
系统内置函数 和 程序员自定义函数
定义函数
function 函数名([参数列表]){
函数体
}
结构说明:
·function它是定义函数的关键字 不可以省略。
·函数名它的命名规则与变量名是一样的
·函数名后面紧跟着一对小括号 这一对小括号不能省略
·小括号里面可能有参数,我们将其称之为形参
·小括号后面紧跟着一对大括号 这一对大括号不能省略
·大括号里面是函数体
注意:函数定义了一定要调用函数
调用函数
格式:
函数名([实参列表])
注意:在定义函数时如果有形参 反过来说 在调用的时候也要有实参 但是这个不是绝对的!
同名函数后面的会将前面的覆盖
函数一定是先定义后再调用
函数的参数
函数的参数分为两种:
形式参数和实际参数
形式参数:在定义函数的时候的参数就称之为形式参数,简称“形参”。在定义函数的时候 在函数名的后面的小括号里面给的变量名。
实际参数:在调用函数的时候的参数就称之为实际参数,简称“实参”。
在一个函数中,参数的多少是根据功能来定义的!
使用函数来动态的输出M行N列的表格
一般在函数体里面不会有输出语句,只会有一个return关键字,将我们要输出的内容返回给函数的调用者。
·return在英文中表示“返回”的意思
·return关键字是在函数体里面使用。
它在函数体使用有两层含义:
2.它会向函数的调用者返回数据(重点)返回值
格式:return数据;
在调用函数时可以定义一个变量要接收到这个函数的返回值
注意:
我们在以后的工作中,函数体里面尽量不要有输出语句(document.write alert console.log ),尽量的使用return关键字将数据返回给函数的调用者。
特别强调:
·在一个函数里面,return关键字可以有多个,但是return只会执行一次;
·return关键字它只能返回一个数据,如果需要返回多个数据,我们可以将多个数据使用数组的方式来保存,然后再将数组返回。
匿名函数
什么是匿名函数?
没有名字的函数 称之为匿名函数!注意:匿名函数在JS中使用最多。
匿名函数也是需要调用的!
将匿名函数赋值给变量或者是事件
a)将匿名函数赋值给变量,然后通过变量名加上小括号来调用匿名函数
b)将匿名函数赋值给事件 *****
将匿名函数赋值给事件,那么匿名函数什么时候才会执行?它要等到事件触发了以后,匿名函数才会执行。
什么是变量的作用域?
指变量在什么地方可以使用,什么地方不可以使用。
变量作用域的分类
变量作用域分为:全局作用域和局部作用域。
变量的作用域是通过函数来进行划分的。
在函数外面定义的变量我们将其称为全局变量,它的作用域是全局的。
全局作用域: 在任何地方都可以访问到的变量就是全局变量,对应全局作用域
局部作用域: 在固定的代码片段内可访问到的变量,最常见的例如函数内部。对应局部作用域(函数作用域)
问:是否能够提升局部变量的作用域呢?将局部变量的作用域提升至全局作用域。在函数里面定义的变量也能够在函数外面访问到。
只需要将函数里面定义的变量的var关键字给去掉就可以实现将局部变量的作用域提升至全局作用域。
但是:并不建议直接就var 关键字给省略,我们建议在函数的外面定义一个同名的全局变量。
avaScript是一种发展迅速的语言。这篇文章,我想展示一些有关如何在JavaScript中应用函数式编程的示例。
即使函数式编程可以极大地改善应用程序的代码,但其原理在开始时可能会有些挑战。由于详细解释所有这些都将花费大量时间,因此我们决定使用两个实际的代码示例来介绍这些概念
在第一个示例中,我们找到一种避免验证变量是否为Null的方法。假设在我们的应用程序中,我们可以找到具有以下格式的用户:
const someUser={
name: 'some_name',
email: 'some@email.com',
settings: {
language: 'sp'
}
};
有一个功能,可以以用户设置的语言返回欢迎消息。
const allGreetings={
'en': '嗨',
'sp': '你好',
'fr': '欢迎你'
};
const getGreetingForUser=(user)=> {
//将要执行
}
来看一个遵循命令式模型的“ getGreetingForUser”函??数的实现:
const getGreetingForUser=(user)=> {
if (!user) {
return allGreetings.en;
}
if (user.settings && user.settings.language) {
if (allGreetings[user.settings.language]) {
return allGreetings[user.settings.language]
} else {
return allGreetings.en;
}
} else {
return allGreetings.en;
}
};
console.log(getGreetingForUser(someUser));
如上面所看到的,必须检查用户是否已经存在,是否已设置语言,以及是否已准备好欢迎消息。如果出现问题,我们将以默认语言返回一条消息。
现在,让我们看一下相同的函数,但是这次我们将在其实现中使用函数式编程:
const getGreetingForUser=(user)=> {
return RamdaFantasy.Maybe(user)
.map(Ramda.path(['settings', 'language']))
.chain(maybeGreeting);
};
const maybeGreeting=Ramda.curry((greetingsList, userLanguage)=> {
return RamdaFantasy.Maybe(greetingsList[userLanguage]);
})(allGreetings);
console.log(getGreetingForUser(someUser).getOrElse(allGreetings.en));
为了处理可能为null或未定义的情况,我们将使用Maybe Monad。这使我们可以在对象周围创建包装器,并为空对象分配默认行为。
让我们比较两种解决方案:
//代替验证用户是否为空
if (!user) {
return allGreetings.en;
}
//我们将用:
RamdaFantasy.Maybe(user) //我们将用户添加到包装器中
//代替:
if (user.settings && user.settings.language) {
if (allGreetings[user.settings.language]) {
//我们将用:
<userMaybe>.map(Ramda.path(['settings', 'language'])) //如果存在数据,映射将会用它
//不是在else中返回默认值:
return indexURLs['en'];
.getOrElse(allGreetings。EN)
// 指定的默认值。
当我们知道存在空错误时的默认行为时,Maybe Monad非常有用。
但是,如果我们有一个引发错误的函数,或者我们将各种引发错误的函数链接在一起,并且我们想知道哪个发生了故障,则可以改用Either Monad。
现在,让我们假设我们要计算产品的价格,同时考虑增值税和可能的折扣。我们已经有了以下代码:
const withTaxes=(tax, price)=> {
2
if (!_.isNumber(price)) {
3
return new Error("Price is not numeric");
4
}
5
return price + (tax * price);
6
};
7
const withDiscount=(dis, price)=> {
8
if (!_.isNumber(price)) {
9
return new Error("Price is not numeric");
10
}
11
if (price < 5)
12
return new Error("Discounts not available for low-priced items");
13
}
14
return price - (price * dis);5
};
const isError=(e)=> e && e.name==='Error';
const calculatePrice(price, tax, discount)=> {
//将要执行
}
让我们来看一个遵循命令式模型的“ calculatePrice”函数的实现:
const calculatePrice=(price, tax, discount)=> {
const priceWithTaxes=withTaxes(tax, price);
if (isError(priceWithTaxes)) {
return console.log('Error: ' + priceWithTaxes.message);
}
const priceWithTaxesAndDiscount=withDiscount(discount, priceWithTaxes);
if (isError(priceWithTaxesAndDiscount)) {
return console.log('Error: ' + priceWithTaxesAndDiscount.message);
}
console.log('Total Price: ' + priceWithTaxesAndDiscount);
}
//我们计算出价值25的产品(含21%的增值税和10%的折扣)的最终价格。
calculatePrice(25, 0.21, 0.10)
现在,让我们了解如何使用Either Monad重写此函数。
都有两个构造函数,Left和Right。我们要实现的是将异常存储到Left构造函数,并将正常结果(快乐路径)存储到Right构造函数。
首先,将更改已经存在的withTaxes和withDiscount函数,以便在出现错误时它们返回Left,在一切正常的情况下返回Right:
const withTaxes=Ramda.curry((tax, price)=> {
if (!_.isNumber(price)) {
return RamdaFantasy.Either.Left(new Error("Price is not numeric"));
}
return RamdaFantasy.Either.Right(price + (tax * price));
});
const withDiscount=Ramda.curry((dis, price)=> {
if (!_.isNumber(price)) {
return RamdaFantasy.Either.Left(new Error("Price is not numeric"));
}
if (price < 5) {
return RamdaFantasy.Either.Left(new Error("Discounts not available for low-priced items"));
}
return RamdaFantasy.Either.Right(price - (price * dis));
});
然后,我们为Right案例创建一个函数(显示价格),为Left案例创建另一个函数(显示错误),然后使用它们创建Either Monad:
const showPrice=(total)=> { console.log('Price: ' + total) };
const showError=(error)=> { console.log('Error: ' + error.message); };
const eitherErrorOrPrice=RamdaFantasy.Either.either(showError, showPrice);
最后,只需要执行Monad来计算最终价格:
//计算出价值25的产品(含21%的增值税和10%的折扣)的最终价格。
eitherErrorOrPrice(
RamdaFantasy.Either.Right(25)
.chain(withTaxes(0.21))
.chain(withDiscount(0.1))
)
正如我们所看到的,一旦用Maybe和Either单子分解了代码,就没有那么复杂了。如果使用得当,它们可以使我们的代码更易于阅读和维护。
唯一的不便是我们需要克服的初始障碍,但这可以通过在网上一些示例并进行一些测试来完成。
喜欢可以关注一下哦。
半夜的一次斜眸,我发现了支付宝灰色产业的一角
得知开源会削弱对中国的技术封锁,特朗普气炸了
用漫画让你清楚了解linux内核,看懂了么?
你用大量 if else,而不用switch的原因,if真香啊
能在996公司久呆的人,到底有多会划水?
当网站需要生成随机颜色时,我们可以通过以下代码来执行此操作。
对数组元素重新排序是一个非常重要的技巧,但它在原生数组中不可用。
复制到剪贴板是一项非常有用且用户友好的功能。
深色主题越来越流行,很多用户会在设备上启用暗模式。我们将应用程序切换到深色主题以改善用户体验。
将元素滚动到顶部的最简单方法是使用 scrollIntoView。设置块开始滚动到顶部;将行为设置为平滑以启用平滑滚动。
就像滚动到顶部一样,滚动到底部只是将块设置为结束。
检查元素是否在窗口中的最佳方法是使用 IntersectionObserver。
使用 navigator.userAgent 检测网站在哪个平台设备上运行。
我们可以将元素的 style.visibility 设置为 hidden 来隐藏元素的可见性,但是,元素的空间还是会被占用。将元素的 style.display 设置为 none 将从渲染流中删除该元素。
JavaScript中有一个URL对象,可以很方便的获取URL中的参数。
深度复制对象非常简单。首先,将对象转换为字符串,然后将其转换为对象。
除了使用 JSON 的 API 之外,还有一个更新的结构化克隆 API,用于深度复制对象,并非所有浏览器都支持该 API。
JavaScript 提供了 setTimeout 函数,但是,它没有返回 Promise 对象,所以我们不能在这个函数上使用 async,但是,我们可以封装等待函数。
警告:warning::当你不确定他们的属性是否存在或不在数据中时使用可选链接。如果您确定密钥必须传入数据,并且如果没有出现,那么,最好是抛出错误而不是阻止它们。
将与 OR (||) 运算符混淆??
如果值不真实(0,'',null,undefined,false,NaN),当您想要有条件地分配其他值时使用 OR 运算符。
以上就是我今天与你分享的全部内容,如果你觉得有用的话,请记得点赞我,关注我,并将它分享给你身边的朋友,也许能够帮助到他。
最后,谢谢你的阅读,祝编程愉快!
来源:https://www.51cto.com/article/717001.html
*请认真填写需求信息,我们会在24小时内与您取得联系。