函数是一段可以反复调用的代码块
函数的声明
JavaScript 有三种声明函数的方法
function
命令: function
命令声明的代码区块,就是一个函数。function
命令后面是函数名,函数名后面是一对圆括号,里面是传入函数的参数。函数体放在大括号里面。function print(s) {
console.log(s);
}
function
命令声明函数,还可以采用变量赋值的写法var print = function(s) {
console.log(s);
};
var add = new Function(
'x',
'y',
'return x + y'
);
// 等同于
function add(x, y) {
return x + y;
}
温馨提示
这种声明函数的方式非常不直观,几乎无人使用
如果同一个函数被多次声明,后面的声明就会覆盖前面的声明
function f() {
console.log("sxt");
}
f() // itbaizhan
function f() {
console.log("itbaizhan");
}
f() // itbaizhan
JavaScript 引擎将函数名视同变量名,所以采用function
命令声明函数时,整个函数会像变量声明一样,被提升到代码头部。
add();
function add() {}
但是,如果采用赋值语句定义函数,JavaScript 就会报错。
add();
var add = function (){};
// TypeError: undefined is not a function
温馨提示
不能在条件语句中声明函数
根据 ES5 的规范,不得在非函数的代码块中声明函数,最常见的情况就是if
语句
if (true) {
function add() {}
}
function add() {}
add.name // "add"
如果是通过变量赋值定义的函数,那么name属性返回变量名
var add = function () {};
add.name // "add"
name属性的一个用处,就是获取参数函数的名字
var myFunc = function () {};
function test(fn) {
console.log(fn.name);
}
test(myFunc) // myFunc
length 属性
函数的length属性返回函数预期传入的参数个数,即函数定义之中的参数个数
function add(a, b) {}
add.length // 2
toString()
函数的toString方法返回一个字符串,内容是函数的源码
function add() {
a();
b();
c();
}
add.toString()
// function add() {
// a();
// b();
// c();
// }
作用域(scope)指的是变量存在的范围,Javascript 有两种作用域:一种是全局作用域,变量在整个程序中一直存在,所有地方都可以读取;另一种是函数作用域,变量只在函数内部存在函数外部声明的变量就是全局变(globalvariable),它可以在函数内部读取
var num = 1;
function add() {
console.log(num);
}
add()
// num
在函数内部定义的变量,外部无法读取,称为“局部变量”(localvariable)
function add(){
var num = 1;
}
num // ReferenceError: num is not defined
函数内部定义的变量,会在该作用域内覆盖同名全局变量
var num = 1;
function add(){
var num = 2;
console.log(num);
}
add() // 2
num // 1
注意,对于var命令来说,局部变量只能在函数内部声明,在其他区块中声明,一律都是全局变量
if (true) {
var num = 5;
}
console.log(num); // 5
函数内部的变量提升
与全局作用域一样,函数作用域内部也会产生“变量提升”现象。var
命令声明的变量,不管在什么位置,变量声明都会被提升到函数体的头部
function foo() {
console.log(names);
var names = 'itbaizhan';
}
foo()
概述
函数运行的时候,有时需要提供外部数据,不同的外部数据会得到不同的结果,这种外部数据就叫参数
function square(x) {
console.log(x * x);
}
square(2) // 4
square(3) // 9
参数的省略
函数参数不是必需的,Javascript 允许省略参数
function add(a, b) {
console.log(a);
}
add(1, 2, 3) // 1
add(1) // 1
add() // undefined
add.length // 2
传递方式
函数参数如果是原始类型的值(数值、字符串、布尔值),传递方式是传值传递(passes by value)。这意味着,在函数体内修改参数值,不会影响到函数外部
var p = 2;
function fn(p) {
p = 3;
}
fn(p);
p // 2
同名参数
如果有同名的参数,则取最后出现的那个值
function add(a, a) {
console.log(a);
}
add(1, 2) // 2
arguments 对象
由于 JavaScript 允许函数有不定数目的参数,所以需要一种机制,可以在函数体内部读取所有参数。这就是arguments
对象的由来
var list = function (one) {
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
}
list(1, 2, 3)
arguments 与数组的关系
需要注意的是,虽然arguments
很像数组,但它是一个对象。数组专有的方法(比如slice
和forEach
),不能在arguments对象上直接使用。
如果要让arguments
对象使用数组方法,真正的解决方法是将 arguments
转为真正的数组
var args = [];
for (var i = 0; i < arguments.length; i++) {
args.push(arguments[i]);
}
函数返回值
JavaScript函数提供两个接口实现与外界的交互,其中参数作为入口,接收外界信息;返回值作为出口,把运算结果反馈给外界。
在函数体内,使用 return
语句可以设置函数的返回值。
function getName(name){
return name;
}
可以定义一个变量,来接收该结果
function getName(name){
return name;
}
var myName = getName("itbaizhan")
console.log(myName); // itbaizhan
如果return
语句后不跟任何值就相当于返回一个undefined
,如果函数中不写 return,则也会返回undefined
function getName(name){
return;
}
var myName = getName("itbaizhan")
console.log(myName); // undefined
function getName(name){
}
var myName = getName("itbaizhan")
console.log(myName); // undefined
在函数中return
后的语句都不会执行
function getName(name){
return name;
console.log("我不会执行");
}
var myName = getName("itbaizhan")
console.log(myName);
在 Javascript 中,圆括号()
是一种运算符,跟在函数名之后,表示调用该函数。比如,print()
就表示调用print
函数。那如何让函数自己执行呢
(function(){ /* code */ }());
// 或者
(function(){ /* code */ })();
自执行函数传递参数
var a = 10;
var b = 20;
(function(a,b) {
console.log(a+b);
})(a,b);
eval 命令
eval
命令的作用是,将字符串当作语句执行
eval('var a = 1;');
a // 1
实现一个函数,要求传入数组,返回排序之后的数组
function mySort(arr) {
for (var i = 0; i < arr.length - 1; i++)
{
for (var j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr
}
实现阶乘:5!的结果
function fact(num){
if(num<=1){
return 1
}else{
return num*fact(num-1)
}
}
什么是对象?对象(object)是 JavaScript 语言的核心概念,也是最重要的数据类型
简单说,对象就是一组“键值对”(key-value)的集合,是一种无序的复合数据集合
var user = {
name: 'itbaizhan',
age: '13'
};
如果键名不符合标识名的条件(比如第一个字符为数字,或者含有空格或运算符),则必须加上引号,否则会报错
// 报错
var obj = {
1p: 'Hello World'
};
// 不报错
var obj = {
'1p': 'Hello World',
'h w': 'Hello World',
'p+q': 'Hello World'
};
对象的每一个键名又称为“属性”(property),它的“键值”可以是任何数据类型。如果一个属性的值为函数,通常把这个属性称为“方法”,它可以像函数那样调用
var user = {
getName: function (name) {
return name;
}
};
user.getName("itbaizhan") // itbaizhan
如果属性的值还是一个对象,就形成了链式引用
var user = {
name:"itbaizhan",
age:13,
container:{
frontEnd:["Web前端","Android","iOS"],
backEnd:["Java","Python"]
}
}
user.container.frontEnd // ["Web前端","Android","iOS"]
读取属性
读取对象的属性,有两种方法,一种是使用点运算符,还有一种是使用方括号运算符
var user = {
hello: 'Hello World'
};
user.hello // "Hello World"
user['hello'] // "Hello World"
温馨提示
如果使用方括号运算符,键名必须放在引号里面,否则会被当作变量处理
属性的赋值
点运算符和方括号运算符,不仅可以用来读取值,还可以用来赋值
var obj = {};
obj.name = 'itbaizhan';
obj['age'] = 13;
JavaScript 允许属性的“后绑定”,也就是说,你可以在任意时刻新增属性,没必要在定义对象的时候,就定义好属性
var user = { name: "itbaizhan" };
// 等价于
var user = {};
user.name = "itbaizhan";
查看所有属性
查看一个对象本身的所有属性,可以使用Object.keys
方法
var user = {
key1: 1,
key2: 2
};
Object.keys(user); // ['key1', 'key2']
delete 命令
delete
命令用于删除对象的属性,删除成功后返回 true
var user = { name: "itbaizhan" };
Object.keys(user) // ["name"]
delete user.name // true
user.name // undefined
Object.keys(user) // []
温馨提示
删除一个不存在的属性,delete
不报错,而且返回true
var user = {};
delete user.name // true
只有一种情况, delete
命令会返回 false
,那就是该属性存在,且不能删除(使用率极低)
for…in 循环
for...in
循环用来遍历一个对象的全部属性
var user = {
name:"itbaizhan",
age:13
};
for (var i in user) {
console.log(user[i]); // itbaizhan 13
}
Object
对象的方法分成两类: Object
本身的方法与 Object
的实例方法
Object 对象本身的方法
所谓”本身的方法“就是直接定义在 Object
对象的方法
Object.print = function (info) {
console.log(info)
};
Object.print("hello");
Object 的实例方法
所谓实例方法就是定义在 Object
原型对象Object.prototype
上的方法。它可以被 Object
实例直接使用
Object.prototype.print = function (name) {
console.log(name);
};
var user = {
name:'itbaizhan'
}
user.print(user.name);
函数中调用函数
现有两个函数 hello()
和 world()
,那么是可以通过一个函数调用另一个函数运行的
函数体使用规范
1 总行数不要超过50行
2 不同的业务分割成不同的函数处理
需求:创建一个函数,传递两个参数,返回两个参数的相乘和相加的和
function result(x,y){
var sum = mult(x,y) + add(x,y);
console.log(sum)
}
function mult(x,y){
return x * y;
}
function add(x,y){
return x + y;
}
Math与Date