导读
- 函数是什么
- 创建函数的方法
- 调用函数的方法
- 变量作用域
- 变量声明提升
- 函数也是数据
- 使用函数思想写程序的思路
函数是什么
函数是执行特定任务的代码块(代码块就是使用大括号包裹起来的语句的集合)。本质上函数是一种代码的分组形式。我们可以通过函数这种形式赋予某组代码一个名字,以便于之后调用。
示例:函数和函数调用
//函数声明
function sum(a,b){
return a + b
}
//函数调用
sum(2,3) //5
特点1:函数只定义一次,可被调用任意次。
特点2:定义的函数永远不会执行,除非你调用它。
创建函数的方法
函数声明的语法:
function funtionName(parameter1, parameter2, parameter3) {
// code to be executed
}
函数声明是创建函数的一种方法。函数声明的过程通常由以下几部分构成。
1.function:关键词,用于声明函数。
2.函数名称:声明函数会创建一个变量,函数名称就是变量的名称,这是理解函数的关键。函数名称用于存放代码块。代码块相当于变量的值。
3.形参:形参就是变量,只是省略的声明变量的关键词var。它是小括号里用逗号分隔的参数。一个函数通常具有0个或多个形参。形参用于接收在函数调用时通过形参传入函数内的实参。
4.函数体 :使用大括号包裹的代码块。函数体相当于函数名的值。
5.return语句:如果你希望函数运行之后计算一个值,需要在函数内使用return语句显示设置返回值。return语句不是必须设置的,如果你没有在函数体内设置return语句,那么函数默认的返回值是undefiend。注意:一个函数只能有一个返回值,如果你需要返回多个值,可以考虑将多个值放入一个数组里,以数组元素的形式返回。
示例: 声明一个求平方的函数
function square(a){
return a * a
}
示例: 声明一个判断一个字符串是否是包含数字的函数
function square(a){
return a * a
}
示例: 声明一个判断一个值是否是奇数的函数
示例: 声明一个1位数字前置补0的函数
调用函数的方法
当创建了一个函数之后,如果需要使用它,就必须要去调用它,调用函数的方法很简单,只需要在函数名后加一对小括号即可。小括号内传入实际的参数,如果有多个参数,请使用逗号分隔。
语法
funtionName( 实参1,实参2,实参3,...,实参N )
- 实参: 是调用函数时,通过形参传入到函数内的实际的参数。所有的实参都是为了计算函数返回值而出现的。
示例: 调用square()函数
square(10) // 100
思考:形参数量和实参数量是否必须一致?答案是否定的。了解相关内容,请查阅“arguments'对象。作为函数的初学者,最好让形参与实参数量保持一致。
变量作用域
变量作用域指定义变量的区域。 变量在哪个区域定义,就在哪个区域发生作用。变量作用域决定了变量的可访问性。在当前定义区域内,变量可以被访问到,在这个区域以外,变量不能被访问到。
有两种类型的作用域:
- 全局作用域:局部作用域之外的区域就是全局作用域。
- 局部作用域:局部作用域指函数作用域和块级作用域。这两种局部作用域使用不同的关键词
-
定义:
- 函数作用域:指在函数体内,使用关键词var定义的变量,会创建变量的函数作用域,也就是说变量只能在当前函数体内才可以访问。注:变量定义在if或for创建的代码块内,是不会创建函数作用域的。
- 块级作用域: 指在大括号包裹的区域内,使用关键词let或const定义的变量,会创建块级作用域,只能在大括号内才可以访问。
示例1: 函数作用域
function fn(){
var a = 100
console.log(a) // 100 (在函数体内可访问到变量的值)
}
console.log(a) // Uncaught ReferenceError: a is not defined(在函数体外访问不到变量的值)
示例2: let定义的变量存在块级作用域
{
let a = 100
console.log(a) // 100
}
console.log(a) // Uncaught ReferenceError: a is not defined
示例3: let定义的变量存在块级作用域(if语句)
if(true){
let a = 100
console.log(a) // 100
}
console.log(a) // Uncaught ReferenceError: a is not defined
示例4: let定义的变量存在块级作用域(for语句)
for (let i = 0; i < 3; i++) {
console.log(i) // 0, 1, 2
}
console.log(i) // Uncaught ReferenceError: i is not defined
示例5: var定义的变量不存在块级作用域
{
var a = 100
console.log(a) // 100
}
console.log(a) // 100
示例6: var定义的变量不存在块级作用域
if(true){
var a = 100
console.log(a) // 100
}
console.log(a) // 100
示例7: var定义的变量不存在块级作用域
for (var i = 0; i < 3; i++) {
console.log(i) // 0, 1, 2
}
console.log(i) // 3
示例
console.log(a) //
var a = 1
示例
console.log(a) //
let a = 1
示例
{
var a = 1
}
console.log(a) //
示例
{
let a = 1
}
console.log(a) //
示例
var a = 1
function fn(){
alert(a) //
var a = 2
}
fn()
alert(a) //
示例
var a = 1
function fn(){
alert(a) //
a = 2
}
fn()
alert(a) //
示例
var a = 1
function fn(a){
alert(a) //
a = 2
}
fn(a)
alert(a) //
示例
var a = 1
function fn(a){
alert(a) //
a = 2
}
fn()
alert(a) //
示例
var str = ''
function fn(){
var a = 'hello'
str = a
}
fn()
alert(str) //
示例
function fn1(){
var a = 'hello'
fn2(a)
}
fn1()
function fn2(a){
alert(a) //
}
示例
var a = 0
function fn1(){
a++
}
function fn2(){
a--
}
fn2()
fn1()
fn2()
alert(a) //
示例
alert(a)
if(true){
var a = 1
}
示例
alert(fn)
function fn(){
alert(123)
}
示例
alert(fn()) //
function fn(){
alert(123)
}
示例
alert(fn)
if(true){
var a = 1
function fn(){
alert(123)
}
}
示例
alert(fn) //
var a = 1
function fn(a){
alert(a)//
}
示例
alert(fn()) //
var a = 1
function fn(a){
alert(a)//
}
示例
foo(); //
var a = true;
if (a) {
function foo() { console.log("a"); }
}
else {
function foo() { console.log("b"); }
}
变量声明提升
变量声明提升是关于函数作用域的一个重要问题。先看一个的例子:
//请问console.log()第一次输出的是什么?
var n = 123
function fn(){
console.log(n) //?
var n = 456
console.log(n)
}
fn()
您可能会想当然第认为第一次console.log()输出的是123,也就是全局变量n的值。但事实并非如此,第一个console.log()实际上输出的是undefined。因为在函数体内:变量n也有定义,故局部变量n会覆盖全局变量n。尽管在函数体内,第一次调用局部变量n的时候,n还没有定义,但n实际上已经存在于本地空间(函数体内)了,这种特殊现象叫做提升(hoisting) 。
提升(hoisting) :指当JS执行过程进入新函数时,新函数内的的所有变量声明(如var n)都会被提升到当前作用域的顶部。
示例:模拟变量声明提升
/**********************
var n //变量声明被提升至顶部
*********************/
console.log(n) //undefined(在这里可以读取到n的原因就在于变量声明提升)
var n = 123
示例:模拟变量声明提升
/**********************
var n //变量声明被提升至顶部
*********************/
console.log(n) // undefined(在这里可以读取到n的原因就在于变量声明提升)
var n = 123
function fn(){
/*****变量声明被提升至顶部******
var n
*************************/
console.log(n) //undefined(在这里可以读取到n的原因就在于变量声明提升)
var n = 456
console.log(n)
}
fn()
示例: 模拟函数提升
/********整个函数被提升到顶部**********
function fn(){
console.log('hello world')
}
*******************************/
fn() // 'hello world' (在这里可以读取到fn()的原因就在于函数提升)
function fn(){
console.log('hello world')
}
函数声明也会创建变量,所以函数声明也会发生变量提升,与变量声明提升不同的是,整个函数,包括函数声明与函数体都会被提升至当前作用域顶部。
函数也是数据
在JavaScript中,函数实际上也是一种数据。这种特殊的数据类型由两个重要特性:
- 它们包含的是语句
- 它们是可执行的
既然函数是一种数据类型。也就是说,我们可以把一个函数赋值给一个变量。
这是创建函数的第二种方法叫做:函数表达式。创建函数表达式的语法是:
函数定义表达式
var myFunction = function name([param[, param[, ... param]]]) { statements }
示例
//定义函数
var fn = function(a,b){
return a + b
}
//调用函数
fn(2,3) //5
函数表达式和函数声明其实是不同的,两者的差别表现在它们所在的上下文。函数声明只会出现在程序代码里。
使用函数思想写程序的思路
- HTML结构:请务必一致
- 实现1个核心程序
- 传参