今天完成的事:函数深度学习、作用域与闭包
## 函数
重复代码:让程序难以维护
函数主要用于减少重复代码
函数体的代码不会直接运行,必须要手动调用函数,才能运行其中的代码。
## 函数提升
通过字面量声明的函数,会提升到脚本块的顶部。
通过字面量声明的函数,会成为全局对象的属性。
## 其他特点
通过typeof 函数名,得到的结果是"function"
函数内部声明的变量:
1. 如果不使用var声明,和全局变量一致,表示给全局对象添加属性
2. 如果使用var声明,变量提升到所在函数的顶部,函数外部不可以使用该变量
**函数中声明的变量,仅能在函数中使用,在外部无效**
## 参数
参数表示函数运行的未知条件,需要调用者告知的数据
// 参数的有效返回在函数体中
function 函数名(形参1, 形参2, ...){
}
函数名(实参)
如果实参没有传递,则对应的形参为undefined
## 返回值
函数运行后,得到的结果,调用函数时,调用表达式的值就是函数的返回值
return 会直接结束整个函数的运行
return 后面如果不跟任何数据,返回undefined
如果函数中没有书写return,则该函数会在末尾自动return undefined。
## 文档注释

# 作用域和闭包
## 作用域
作用域表示一个代码区域,也表示一个运行环境
JS中,有两种作用域:
1. 全局作用域
直接在脚本中书写的代码
在全局作用域中声明的变量,会被提升到脚本块的顶部,并且会成为全局对象的属性。
2. 函数作用域
函数中的代码
在函数作用域中声明的变量,会被提升到函数的顶部,并且不会成为全局对象的属性.
**因此,函数中声明的变量不会导致全局对象的污染**
**尽量的把功能封装在函数中**
但是,当函数成为一个表达式时,它既不会提升,也不会污染全局对象。
将函数变为一个函数表达式的方式之一,将函数用小括号括起来。
然而,这样一来,函数无法通过名称调用。
如果书写一个函数表达式,然后将立即调用,该函数称之为立即执行函数 IIFE(Imdiately Invoked Function Expression)。
由于大部分情况下,函数表达式的函数名没有实际意义,因此,可以省略函数名。
没有名字的函数,称之为匿名函数
## 作用域中可以使用的变量
全局作用域只能使用全局作用域中声明的变量(包括函数)
函数作用域不仅能使用自身作用域中声明的变量(包括函数),还能使用外部环境的变量(包括函数)
有的时候,某个函数比较复杂,在编写的过程,可能需要另外一些函数来辅助它完成一些功能,而这些函数仅仅会被该函数使用,不会在其他位置使用,则可以将这些函数声明到该函数的内部。
函数内部声明的变量和外部冲突时,使用内部的。
## 闭包
闭包(closure),是一种现象,内部函数,可以使用外部函数环境中的变量。
训练:
/**
* 判断一个数是不是奇数
* @param {number} n 输入需要判断的数
* @returns {boolean}
*/
function isOdd(n) {
return n % 2 !== 0;
}
/**
* 判断一个数是不是素数
* @param {number} n 输入需要判断的数
* @returns {boolean}
*/
function isPrime(n) {
if (n < 2) {
return false;
}
for (var i = 2; i < n; i++) {
if (n % i === 0) {
return false;
}
}
return true;
}
/**
* 对一个数组进行求和
* @param {number} arr 需要求和的数组
* @returns {number}求和结果
*/
function sumOfArray(arr) {
var arrs = 0;
for (var i = 0; i < arr.length; i++) {
arrs += arr[i];
}
return arrs;
}
/**
* 找出该数组中最大的数
* @param {number} arr 数组
* @returns {number} 返回最大数
*/
function maxOfArray(arr) {
if(!arr.length){
return"不是数组";
}
var arrmax = arr[0];
for (var i = 1; i < arr.length; i++) {
if (arrmax < arr[i]) {
arrmax = arr[i]
}
}
return arrmax;
}
/**
* 求该数组中最小的数
* @param {number} arr
* @returns {number} 返回最小数
*/
function minOfArray(arr) {
if(!arr.length){
return"不是数组";
}
var minArr = arr[0];
for (var i = 1; i < arr.length; i++) {
if (minArr > arr[i]) {
minArr = arr[i]
}
}
return minArr;
}
/**
* 检测该数组是否为稀松数组
* @param {number} arr
* @returns {boolean}
*/
function hasEmptyInArray(arr) {
var empty = false;
for (var i = 0; i < arr.length; i++) {
if (arr[i] === undefined) {
empty = true;
}
}
return empty;
}
/**
* 判断该年是不是闰年
* @param {number} year
*/
function isLesp(year){
return (year%4===0&&year%100!==0||year%400===0)
}
/**
* 返回该年该月的天数
* @param {number} year
* @param {number} month
*/
function getDays(year,month){
if(month===2){
return isLesp(year)?29:28;
}
return month<8&&isOdd(month)||month>=8&&!isOdd(month)? 31:30;
}
/**
* 查找并返回出现频率最高的数字和次数
* @param {number} arr
* @returns {object} 返回键值对(name:freq)
*/
function getTopFreqInArray(arr) {
var topFreq = {};
for (var i = 0; i < arr.length; i++) {
var n = arr[i];
if (topFreq[n]) {
topFreq[n]++
}
else {
topFreq[n] = 1
}
}
var freq;
for (var i in topFreq) {
if (!freq || freq.freq < topFreq[i]) {
freq = {
name: i,
freq: topFreq[i]
}
}
}
return freq;
}
/**
* 哥德巴赫猜想
* @param {number} n
*/
function Goldbach(n){
if(isNaN(n)||n<2||isOdd(n)){
return "输入有误";
}
for(var i=2;i<=n/2;i++){
if(isPrime(i) && isPrime(n-i)){
return `${n}=${i}+${n-i}`
}
}
}
/**
* 输入年数,返回该年的全部月份的天数
* @param {number} year
*/
function monthDays(year){
var a={};
for(var i=1;i<13;i++){
a[i]=getDays(year,i);
}
return a;
}
明天计划的事情:深度学习函数表达式、this、构造函数、递归、DOM事件
遇到的问题:
收获:各种简写骚操作,把js重点知识点深度学一下再进行vue吧,看了视频之后感觉之前学的太浅了
先文档、后视频
评论