1. 函数的声明方式
函数的声明方式有函数声明语句、函数表达式和Function构造函数三种方式。
//1.函数的声明语句
function fn0(){};
fn0();
//2.函数表达式:将一个匿名函数赋值给一个新的变量
var fn1 = function(){};
var fn2 = function hhh(){};//使用非匿名函数赋值,该函数名hhh相当于函数的形参,只能在函数内部使用
//而fn1相当于变量实参,即可在函数内部使用,也可以在外部使用。
//3.Function构造函数
var fn2 = new Function('x','y','return x+y');//括号内接收字符串,最后一项为函数体内语句,之前为参数
2. 函数返回值
- 函数之外使用return会报错;
- 函数之内不使用return,调用表达式时结果是undefined
- 若直接==return;==函数直接终止
- return后的语句不执行,除(try…catch语句)
- 一个函数可以有多个return语句
- 如果函数调用时在前面加上了new’前缀,且返回值不是一个对象或者没有返回值,则返回该函数
//返回值不是一个对象
function fn(){
return 1;
}
var test = new fn();
console.log(test)//fn
//返回值是一个对象
function fn1(){
return {a:1};
}
var test1 = new fn();
console.log(test1)//{a:1}
3.函数调用
3.1 函数调用模式
//1.函数调用模式
function add(x,y){
console.log(this);//在非严格模式下,window对象
//在严格模式下,undefined
return x+y;
}
var sum = add(3,4);
console.log(sum);
//重写
function fn(){
this.a = 1;
console.log(this);
}
fn();
this.a = 4;//覆盖了之前的1
//注意:避免全局属性重写带来的问题。
3.2 方法调用模式
// 2.方法调用模式
var obj = {
//fn称为obj对象的方法
a : 1,
fn:function(){
console.log('111'); // 111
},
fn2:function(){
this.a = 2;// this指向obj
}
}
obj.fn(); // 111
console.log(obj.a)// 1
obj.fn2();
console.log(obj.a)// 2
3.3 构造调用模式
//写法
function fn0(){
return 1;
}
var obj0 = new fn0;//()可以省略
console.log(obj0)
// 传参
function fn(x){
this.a = x;
}
var obj = new fn(2); // 指向当前函数
obj()
console.log(a)
3.4 间接调用模式
var obj = {a:5};
function sum(x,y){
return x+y+this.a;
}
console.log(sum(1,2)); // NaN, this->sum
console.log(sum.call(obj,1,2));// 8 this ->obj
console.log(sum.apply(obj,[1,2]));// 8 this -> obj
4. 函数参数
//arguments:实参(类)数组
function add(x){
return x+1;
}
console.log(add(1)); //2
console.log(add('1')); //'11'
console.log(add()); //NaN
console.log(add(1,2,3)); //2
//非严格模式下,允许函数出现同名形参,值取最后一个同名参数
function add1(x,x,x){
return x;
}
console.log(add(1,2,3)); // 3
//参数个数
// 实参比形参个数少,剩下的形参都将设置为undefined
function add2(x,y){
console.log(x,y);
}
add2(1); //NaN
// 实参比形参多,考虑使用arguments
function add3(){
console.log(arguments[0],arguments[1],arguments[2])
}
add3(1,2,3);//1 2 3
5. 函数重载
重载:定义相同的函数名,传入不同的参数,JS中不存在重载,只能模拟
function add(a){
return a + 100;
}
function add(a,b){
return a + b + 100
}
console.log(add(10)); // NaN
// 模拟重载
function add1(){
if(arguments.length == 0){
return 100;
}else if(arguments.length == 1){
return arguments[0] + 100;
}else if(arguments.length == 2){
return arguments[0] + arguments[1] + 100;
}
}
console.log(add()); //100
console.log(add(10)); //110
console.log(add(10,1)); //111
6. 参数传递
6.1 基本数据类型
number、string、boolean、NaN、undefined
//1. 基本数据类型:将参数直接传递给函数
function add(num){
num = num +10;
return num;
}
var count = 20;
var result = add(count);
console.log(result);
6.2 引用数据类型
Array、Object、Function
//2. 引用参数类型: 会将该参数在内存中的地址复制给局部变量
function setName(obj){
obj.name = 'zjn';
console.log(person.name);// zjn
obj = new Object();
obj.name = 'test';
console.log(obj.name); // zjn
}
var person = new Object();
setName(person);
console.log(person.name);
7. 函数属性
function add(x,y){
console.log(arguments.length); // 4
console.log(add.length) // 2
}
add(2,3,4,5)
function fn(){};
console.log(fn.name); // fn
var fn1 = function (){};
console.log(fn1.name)// fn1
var fn2 = function test(){};
console.log(fn2.name)// test
function pr(){};
console.log(pr.prototype);
fn.prototype.a = 1;
console.log(fn.prototype); //包括 a:1的对象
注:关于原型后面有专门的介绍
8. 函数的方法
//函数的方法继承于父级函数的prototype中,根为构造函数Function();
// 有两个非继承的方法:apply、call
// aplly({obj},[1,2,3])
// call({obj},1,2,3)
window.color = 'red';
var obj ={
color: 'blue'
}
function sayColor(){
console.log(this.color);
}
sayColor();// red
sayColor.call(null)//red 严格模式下不可用!!!
sayColor.call(this);//red
sayColor.call(window); // red
sayColor.call(obj); // blue
sayColor.apply(undefined)//red 严格模式下不可用!!!
sayColor.apply(this);//red
sayColor.apply(window); // red
sayColor.apply(obj); // blue
//1. 找出数组的最大元素
//正常方式
var max = Math.max(1,6,5,18,4,8);
//apply方式
var arr = [1,6,5,18,4,8]
var max2 = Math.max.apply(null,arr);
console.log(max,max2); // 18 18
//2. 将类数组转化为真数组
function add(){
var arr = Array.prototype.slice.apply(arguments)
console.log(arr); // [1,6,5,4,6,4,8,3,4]
}
add(1,6,5,4,6,4,8,3,4)
//3. 数组追加
var arr = [];
Array.prototype.push.apply(arr,[1,2,3,5,4])
console.log(arr); // [1,2,3,5,4]
//4. 利用call和apply做继承
function Animal(name,age){
this.name = name;
this.age = age;
this.sayAge = function(){
console.log(this.age);
}
}
function Dog(nam,age){
// 继承Animal
Animal.call(this,name,age);
}
var c = new Dog('大黄',22); // this -> 实例化 c
c.sayAge()
//5. 使用log代理console.log()
function log(str){
console.log.apply(console,arguments)
}
var p = '哈哈哈哈'
log(p)// 哈哈哈哈
// bind()方法:es5新增的方法,主要作用--将函数绑定到某个对象中,并且有返回值
function fnb(y){
return this.x +y;
}
var x =2;
console.log(fnb(2)) // 4 此时this -> window, x = 2
var obj = {x:10};
console.log(fnb.bind(obj)(2)); // bind(obj)将this -> obj, x = 10;
// 常见的函数式编程 -- 函数柯里化
function getConfig(color, size, otherOptions){
console.log(color,size,otherOptions);
}
var defaultConfig = getConfig.bind(null,'blue','1024*768');
defaultConfig('456'); // 'blue',1024*768,456