JavaScript(六) 函数
一个函数是可以通过外部代码调用的一个“子程序”。函数中可以封装一系列语句,在需要时直接调用该函数。在定义函数时可以将值传递至函数,同时在调用函数时也可以返回一个值
创建与调用函数
1、使用 函数表达式 来创建一个函数
语法:
1 | /* 创建函数 */ |
例:
1 | /* 创建函数 */ |
2、使用 函数声明语句 来创建一个函数
语法:
1 | /* 创建函数 */ |
例:
1 | /* 创建函数 */ |
函数体
函数体为可执行的语句,只在调用函数时执行
形参 与 实参
形参是一个未声明的局部变量,只在调用函数时被声明和赋值
而实参则是对应形参的实际值,可以是任何表达式
形参和实参是可选项可以为空
函数表达式
函数表达式会将该函数( Function类型对象 )作为值返回
在 JavaScript 中 函数表达式 和 函数声明语句 都使用了 function关键字
Js 引擎在解析一条语句时,如果 function关键字前有相关运算符,则会将其作为函数表达式执行,如果没有则会将其作为函数声明语句执行
函数也是对象
在 JavaScript 中函数是一个”Function类型对象”,因此函数和对象的使用是一样的
不同的是函数除了可以添加属性外,还可以封装和调用
return
return
语句用来设置函数的返回值语法:
1 return 表达式例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 /* 例1 */
function sum(a, b, c){
return a+b+c
}
var result = sum(4,7,8); //result 的值为19
/* 例2 */
function fun() {
return {
sey: function () {
return 123;
}
}
}
var s = fun()
console.log(s.sey());return 语句可以终止函数的执行( return 后的语句将不会执行 ),并返回一个指定的值给函数调用表达式( 默认返回 undefined )
函数的返回值可以是任何数据类型
方法(methods)
在对象中如果一个属性值是一个函数,则该属性可以称为该对象的方法
语法:
1 | /* 1.通过对象字面量添加方法 */ |
例:
1 | /* 创建对象 */ |
toString 方法
toString
方法是 Object 类型对象中的一个方法,任何对象都可以使用该方法。该方法用来将任意数据类型转换成字符串并返回在使用
console.log()
输出对象到控制台时其输出值在不同运行环境( 如Chrome、FireFox、Node.js … )会略有不同,默认情况下输出一个对象的值,实际上是输出对象中toString
方法的返回值例:
1
2
3
4
5
6
7
8
9
10 var obj = {name: 'value'};
var arr = [1, 2, 3];
function fun(){}
console.log(obj.toString()); // [object Object]
console.log(arr.toString()); // 1,2,3
console.log(fun.toString()); // function fun(){}
Object.prototype.toString = function () {
return 'is Object';
}
alert(obj); // is Object当两个对象做比较运算( 如
<
>
==
仅相等运算有意义 )时,则是比较对象的引用值( 内存地址 ),其它与对象有关的运算,默认情况下都是和对象的toString
方法的返回值做运算
立即调用函数表达式(IIFE)
立即调用函数表达式 是一个在定义时就会立即执行的函数,也称立即执行函数
它由 函数表达式+()
组成
语法:
1 | (function([形参1, 形参2...形参N]){ |
例:
1 | var str='Hello' |
arguments 对象
arguments
是 Js 引擎在执行时自动向函数中添加的局部变量,其值是一个保存了函数实参的类数组对象(类似数组,但不是数组)
属性:
.length
获取实参的个数.callee
返回当前执行的函数[下标]
根据索引返回或修改实参的值
例:
1 | /* 例1 */ |
全局与局部变量
局部变量
通常函数内声明的变量都为局部变量,在调用函数时函数内声明的变量只在该函数内有效
例:
1 | (function() { |
全局变量
默认情况下,不再函数内声明的变量都为全局变量,如果变量不声明()直接赋值,则该变量直接为全局变量var
全局变量在函数内或函数外都可以访问
例:
1 | /* 例1 */ |
window 对象
默认情况下,全局变量会作为在全局对象
window
的属性和方法存储在 Js 中,访问一个全局变量,默认会从全局对象
window
中访问例:
1
2
3
4
5 var a = 123;
function fun(){
return a;
}
console.log(window.a, window.fun()); //输出:123 123
作用域(scope)
作用域是指一个变量作用的 范围
分类:
- 全局作用域
- 函数作用域
全局作用域中的变量即全局变量,函数作用域中的变量即局部变量
在浏览器中,全局作用域其作用范围是整个页面。函数作用域其作用范围只在函数内
作用域链
函数内可以嵌套多个函数,而作用域则是根据函数代码的层次进行分层,以使子作用域可以访问父级作用域中的变量,而不能从父作用域引用子级作用域中的变量
如果一个变量不 “在当前的作用域中”,则会从父级作用域中查找,即沿着链式的作用域链查找( 就近原则 )
例:
1 | var num = 10; |
当内层函数要访问一个变量时,会先在当前作用域中查找,若不存在,则向上一级作用域中查找,直到找到全局作用域,如果全局作用域中依然没有找到,则会报错 ReferenceError
变量提升(Hoisting)
使用var关键字声明,会在当前作用域中提前声明
例:
1 | console.log(a); //输出:undefined |
使用function关键字声明,会在当前作用域中提前声明
例:
1 | fn(); |
function
声明要比var
声明的优先级更高
例:
1 | console.log(fn.toString()); // [Function: fn] |
PS:JavaScript 中 var 关键字只会提升声明,不会提升其初始化的值,而 function 声明则会将其引用值提升