一、创建函数
(1)字面量的形式创建
function sum(a, b){
return a+b;
}
console.log(sum(1, 2));
var sum = function fun(a, b){
return a+b;
}
// fun(1, 2); 报错:ReferenceError: fun is not defined,原因:变量sum替代了fun作为函数名
console.log(sum(1, 2));
// 所以使用匿名函数
var sum = function (){
return a+b;
}
(2)构造函数的形式创建
var sum = new Function('a', 'b', 'return a+b');
console.log(sum(1, 2));
// 这种创建方式不便于阅读和维护,所以不建议使用
二、函数声明的提升
console.log(sum(1, 2)); // 函数的声明会被提升到当前作用域的最顶部,所以可以在函数声明之前调用
function sum(a, b){
return a+b;
}
注意
// 报错:TypeError: sum is not a function,原因:变量sum的声明被提升,而赋值的函数不会被提升
console.log(sum); // undefined
console.log(sum(1, 2));
var sum = function (a, b){
return a+b;
}
// 报错:TypeError: sum is not a function,原因:变量sum的声明被提升,而赋值的函数不会被提升
console.log(sum(1, 2));
var sum = new Function('a', 'b', 'return a+b');
三、函数的参数
参数分为形参和实参:写在函数括号中的为形参;调用时传递的参数为实参
function sum(a, b){
return a+b;
}
console.log(sum(1, 2)); // 3
console.log(sum(1, 2, 2, 3, 4)); // 3
console.log(sum(1)); // NaN,扩展:NaN与任何值都不相等,包括它自身
console.log(sum()); // Nan
由此可见调用函数时传递的实参个数不受限,无论传递多少个都不会报错,这是因为所有的参数都被保存到一个类似于数组的对象arguments中了,可以通过使用arguments[index]的方式使用参数。
有了arguments,我们就不用使用形参了吗?不,如果不使用形参:书写复杂化;函数参数个数不明确;函数参数的含义不明确
arguments合适的使用场景:参数个数不确定时,例如求和:
function sum(){
var num = null;
for(var item of arguments){
num += item;
}
return num;
}
console.log(sum(1, 2)); // 3
console.log(sum(1, 2, 2, 3, 4)); // 3
四、函数的返回值
function sum(a, b){
return a+b;
console.log(a*b); // 不会被执行
}
console.log(sum(1, 2)); // 3
return相当于函数的结束语句,return之后的代码不会被执行。
五、函数的使用场景
1. 作为值被赋值给其他变量
function sayHello () {
console.log('hello')
}
var sayHi = sayHello;
sayHi(); // 'hello'
sayHello(); // 'hello'
2. 作为对象的属性值
function sayHello () {
console.log('hello')
}
var obj = {
fullName: 'Plus',
sayHi: sayHello
}
obj.sayHi()
3. 作为实参传递给其他函数
words.forEach(function (value, index, self) {
console.log(index, value, self)
})
var sortedwords = words.sort(function (a, b) {
return a.length - b.length
})
console.log(sortedwords)
4. 作为其他函数的返回值
function foo () {
function bar () {
console.log('bar')
}
return bar
}
var func = foo()
func()
5. 作为构造函数,用于创建自定义类型
根据函数的功能,我们可以将函数分成两类:普通函数和构造函数。普通函数用于实现功能(业务逻辑);构造函数用于创建自定义类型的对象。
function Person (fullName, age) {
this.fullName = fullName;
this.age = age;
this.sayHello = function () {
return 'Hello'
};
}
var person1 = new Person('张三', 20);
var person2 = new Person('李四', 19);
console.log(person1);
console.log(person2);
如果构造函数返回值是基本数据类型,不会顶掉new创建出的新对象
如果构造函数返回值是引用类型,会替换掉new创建出的新对象
function Fun1(){
this.fname = '刘能';
this.age = 40;
return [1, 2, 3];
}
var fun1 = new Fun1();
console.log(fun1); // [1, 2, 3] 替换了new创建的新对象
function Fun2(){
this.fname = '刘能';
this.age = 40;
return 'aaa';
}
var fun2 = new Fun2();
console.log(fun2); // Fun2 {fname: "刘能", age: 40}