发表于: 2019-08-21 23:10:44

1 704


今天完成的事:函数深度学习、作用域与闭包

## 函数

重复代码:让程序难以维护

函数主要用于减少重复代码

函数体的代码不会直接运行,必须要手动调用函数,才能运行其中的代码。

## 函数提升

通过字面量声明的函数,会提升到脚本块的顶部。

通过字面量声明的函数,会成为全局对象的属性。

## 其他特点

通过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吧,看了视频之后感觉之前学的太浅了

先文档、后视频



返回列表 返回列表
评论

    分享到