今天学习一下function,它的用途广泛,学问很多,先简单总结下后续再展开
类型
function fn(p1, p2) {
return p1 + p2
}
console.log(typeof fn); // function
console.log(fn instanceof Object) //true
用typeof看属于function,但用 instanceof 可以看出来本质上是object
函数名是一个指向函数对象的指针
重载
js中函数没有重载,后面定义的函数会将之前定义的覆盖掉,
为什么呢?函数名本身只是调用函数时的指针,在重新给函数名赋值后,它就指向了新的函数,也就找不到原来那个函数了
函数声明与表达式
通过函数声明和表达式,都可以创建函数,但它们是有区别的
fn2(); //2
fn1(); //Uncaught TypeError: fn1 is not a function
var fn1 = function () { //通过函数表达式创建
console.log('1');
}
function fn2() { //通过函数声明创建
console.log('2');
}
可以看出,fn1执行时报错,因为根据js中函数优先原则,通过声明创建的函数会自动提升作用于顶部,而表达式会在执行到的时候才定义。
再看个例子:
fn(); //2
var fn = function () {
console.log('1');
}
function fn() {
console.log('2');
}
fn(); //1
怎么回事?两次执行不一样!
这就是函数申明提升到了顶部,而后面执行的表达式定义时将原来的fn覆盖掉了
作为值的用法
函数时可以作为值来作为另一个函数的参数或返回值的,叫做高阶函数
function fn1(p1, p2) {
return p1 + p2;
}
function fn2(fn, p1, p2) {
var p3 = fn(p1, p2);
return function (p4) {
return p3 * p4
};
}
var fn3 = fn2(fn1, 2, 3);
console.log(fn3(4)); //20
高阶函数用到的地方也很多,我们后续学习
内部属性
内部属性就是只能在函数体内使用的,有两个属性,arguments和this,
arguments
arguments是个类数组对象,包含着传入函数的所有参数
它有个属性callee,是个指针,指向拥有这个arguments的函数
callee可以在使用递归时,解除代码与函数名的耦合,例如:
function fn(num) {
if (num == 1) return 1;
//return num + fn(num - 1);
return num + arguments.callee(num - 1);
}
console.log(fn(10)); //55
var fn1 = fn;
fn=null;
console.log(fn1(10)); //55
console.log(fn(10)); //Uncaught TypeError: fn is not a function
在函数名不叫fn或者函数被指向其它函数名时,依然有效
this
this在js中是个很特殊也很重要的对象
this引用的是函数执行的环境对象,通常叫this值
function getname() {
return this.name
}
window.name = 'hahaha';
console.log(getname())
var obj = {
name: 'huhuhu'
}
obj.getname = getname;
console.log(obj.getname());
执行的函数是同一个,但输出不一样,也就是this指向不同
属性和方法
两个属性:length和prototype
length:表示希望接收的参数个数
prototype:叫做原型对象,保存了函数的实例能用到的所有属性方法,不可枚举,在继承用法中发挥重要作用,继承的对象的属性和方法都取自prototype,后续单独介绍
三个方法:apply()、call()、bind()
这三个方法都可以改变函数的this的指向,用法上稍有不同
网友评论