Function是javascript里最常用的一个概念,javascript里的function是最容易入手的一个功能,但它也是javascript最难理解最难掌握的一个概念。
1. Function类型是js中引用类型之一,每个函数实际上都是Function类型的实例对象,具有自己的属性和方法。正因为函数式对象,所以函数名实际上也是一个指向函数对象的指针。
2. 常用的函数定义方式
1. 函数声明:
rush:js;">
function sum(a,b ){
return a+b;
}
2. 表达式:
rush:js;">
var sum = function(){
return a+b;
}; //注意分号
//两种方式的区别:
//解释器会率先读取
函数声明,并使其在执行之前可以访问,而使用表达式则必须等到解析器执行到它所在的
代码行,才会真正被解释执行(变量声明提前,而值留在原地)
alert (sum (10,10));
function sum(a,b){
return a+b;
}
//↑上面的
代码会正常执行,因为在
代码执行前,解析器通过
函数声明提升,读取并将
函数声明
添加到执行环境中,放到
代码树的顶部
alert (typeof sum);
alert(sum(10,10));
var sum = function (a,b){
return a+b;
}
//↑报错,原因在于
函数位于
一个初始化语句中,不是
一个函数声明,不会被提前,而只会把var sum提前,用typeof操作符
显示sum是undefined,所以报错
3. 函数名仅仅保存指向函数对象的指针,因此函数名与包含对象指针的其他变量没什么不同,也就是说,一个函数对象可以有多个名字:
rush:js;">
function sum(a,b ){
return a+b;
}
console.log(sum(2,3)); //5
var anotherSum = sum; //变量anotherSum也指向了同
一个函数对象
console.log(anotherSum(4,5)); //9
sum = null; //sum变量不再保存
函数对象的指针了
console.log(anotherSum(1,3)); //anotherSum这个变量仍能
调用
4. JS为何没有重载这个概念。
rush:js;">
function add(a){
return a+3 ;
}
function add(a){
return a+5;
}
var result = add(3); //8
//两个
函数同名了,结果只能是后
一个函数覆盖前
一个,所以不能重载
5. 函数的内部属性:函数内部,有两个特殊的对象,arguments和this
1. arguments:
arguments是个类数组对象,包含着传入函数的所有参数,这个对象有一个叫callee的属性,属性值是一个指针,指向拥有这个arguments对象的函数本身
rush:js;">
function foo (){
var a =arguments.callee;
return a.toString();
}
foo();
/*
返回结果:
"function sum(){
var a =arguments.callee;
return a.toString();
}"
也就是说,
一个函数内部,arguments.callee指的就是这个
函数本身。这个
函数在递归
调用时有点用,有许多缺陷,在ES5严格模式被移除
*/
2. this:简单来说,this指的就是函数执行的环境对象,在哪个对象中执行,this就指哪个对象。展开来说比较复杂,单开一篇
//Todo:
3. ES5规范了函数的另一个属性:caller,这个函数属性指的是调用当前函数的函数
rush:js;">
function inner(){
console.log(inner.caller);
}
function outer(){
inner();
}
outer();
//function outer(){
inner();
}
4. length属性:表示函数希望接受的参数个数
rush:js;">
function add(a,b,c){
return a+b+c;
}
add.length; //3
5. 著名的prototype属性,简单来说,是一个对象,是通过调用构造函数而创建的一个对象,包含可以由特定类型的所有实例共享的属性和方法。展开来说比较复杂,单开一篇
//Todo:
6. 函数的两个方法:call()和apply(),作用都是在特定的作用域中调用函数,实际上就是设置函数内部的this值
1. call():与apply()方法类似,区别在接收参数的方式不同,参数必须逐个列出来。
2. apply():接收两个参数,一个是函数运行的作用域,另一个是参数数组,可以是数组,也可以是arguments这个类数组对象
rush:js;">
function sum(a,b){
return a+b;
}
function callSum(a,b){
return sum.apply(this,arguments);
}//第二个参数是
一个类数组对象arguments
function callSum1(a,[a,b]);
} //第二个参数是
一个数组
console.log(callSum(2,3)); //5
console.log(callSum1(3,5)); //8
3. 传递参数并调用函数并非call()和apply()的用武之地,二者真正强大的地方是扩充函数运行的作用域
rush:js;">
var color = 'red';
var obj = {
color :'blue'
}
function foo(){
console.log(this.color);
}
foo(); //'red'
foo.call(this);//'red'
foo.call(obj); //'blue'
//最后一次
调用foo()
函数的执行环境变了,其中的this指向了obj对象,所以是'blue'
使用call()和apply()扩充作用域的最大好处,就是使对象与方法之间解耦
4. ES5定义了一个新方法:bind(),返回一个函数,这个函数中this值会被绑定到传给bind()函数的值
rush:js;">
var x = 9;
var module = {
x: 81,getX: function() { return this.x; }
};
module.getX(); // 81
var retrieveX = module.getX;
retrieveX(); // 9,因为
在这种情况下,"this" 指向
全局变量
var boundGetX = retrieveX.bind(module);//把retrieveX()
函数中的this永远与module绑定,再
调用这个
函数永远都是在module对象中运行
boundGetX(); // 81
以上所述是小编给大家介绍的深入浅析JavaScript中的Function类型介绍,希望对大家有所帮助,如果大家想了解更多内容,敬请关注编程之家。
原文地址:https://www.jb51.cc/js/47383.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。