深入浅析JavaScript中的Function类型


Posted in Javascript onJuly 09, 2016

Function是javascript里最常用的一个概念,javascript里的function是最容易入手的一个功能,但它也是javascript最难理解最难掌握的一个概念。

1. Function类型是js中引用类型之一,每个函数实际上都是Function类型的实例对象,具有自己的属性和方法。正因为函数式对象,所以函数名实际上也是一个指向函数对象的指针。

2. 常用的函数定义方式

1. 函数声明:

function sum(a , b ){
return a+b;
}

2. 表达式:

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. 函数名仅仅保存指向函数对象的指针,因此函数名与包含对象指针的其他变量没什么不同,也就是说,一个函数对象可以有多个名字:

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为何没有重载这个概念。

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对象的函数本身

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,这个函数属性指的是调用当前函数的函数

function inner(){
console.log(inner.caller);
} 
function outer(){
inner();
}
outer(); 
//function outer(){
inner();
}

4. length属性:表示函数希望接受的参数个数

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这个类数组对象

function sum(a , b){
return a+b;
}
function callSum(a , b){
return sum.apply(this , arguments);
}//第二个参数是一个类数组对象arguments
function callSum1(a , b){
return sum.apply(this, [a , b]);
} //第二个参数是一个数组
console.log(callSum(2 , 3)); //5 
console.log(callSum1(3 ,5)); //8

3. 传递参数并调用函数并非call()和apply()的用武之地,二者真正强大的地方是扩充函数运行的作用域

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()函数的值

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类型介绍,希望对大家有所帮助,如果大家想了解更多内容,敬请关注三水点靠木。

Javascript 相关文章推荐
JavaScript中String.prototype用法实例
May 20 Javascript
Javascript基于AJAX回调函数传递参数实例分析
Dec 15 Javascript
js中数组结合字符串实现查找(屏蔽广告判断url等)
Mar 30 Javascript
有关jQuery中parent()和siblings()的小问题
Jun 01 Javascript
ionic js 模型 $ionicModal 可以遮住用户主界面的内容框
Jun 06 Javascript
js获取上传文件的绝对路径实现方法
Aug 02 Javascript
javaScript基础详解
Jan 19 Javascript
Javascript 编码约定(编码规范)
Mar 11 Javascript
深入浅析Vue全局组件与局部组件的区别
Jun 15 Javascript
Vue.js图片预览插件使用详解
Aug 27 Javascript
vue路由拦截器和请求拦截器知识点总结
Nov 08 Javascript
JS异步宏队列与微队列原理区别详解
Jul 02 Javascript
JavaScript基础重点(必看)
Jul 09 #Javascript
jQuery获取同级元素的简单代码
Jul 09 #Javascript
JS添加删除DIV的简单实例
Jul 08 #Javascript
js操作DOM--添加、删除节点的简单实例
Jul 08 #Javascript
简单封装js的dom查询实例代码
Jul 08 #Javascript
JS选取DOM元素的简单方法
Jul 08 #Javascript
封装获取dom元素的简单实例
Jul 08 #Javascript
You might like
PHP XML操作的各种方法解析(比较详细)
2010/06/17 PHP
第三章 php操作符与控制结构代码
2011/12/30 PHP
php addslashes及其他清除空格的方法是不安全的
2012/01/25 PHP
PHP采集静态页面并把页面css,img,js保存的方法
2014/12/23 PHP
php微信公众平台开发之获取用户基本信息
2015/08/17 PHP
jquery 事件执行检测代码
2009/12/09 Javascript
jQuery插件实现屏蔽单个元素使用户无法点击
2013/04/12 Javascript
Extjs4 Treegrid 使用心得分享(经验篇)
2013/07/01 Javascript
jquery自定义函数的多种方法
2014/01/09 Javascript
Javascript与jQuery方法的隐藏与显示
2015/01/19 Javascript
基于nodejs+express(4.x+)实现文件上传功能
2015/11/23 NodeJs
js实现的下拉框二级联动效果
2016/04/30 Javascript
第四篇Bootstrap网格系统偏移列和嵌套列
2016/06/21 Javascript
JavaScript中捕获与冒泡详解及实例
2017/02/03 Javascript
BootStrap实现带关闭按钮功能
2017/02/15 Javascript
JS实现线性表的链式表示方法示例【经典数据结构】
2017/04/11 Javascript
javascript编写简易计算器
2017/05/06 Javascript
详解有关easyUI的拖动操作中droppable,draggable用法例子
2017/06/03 Javascript
国内常用的js类库大全(CDN公共库)
2020/06/24 Javascript
[50:05]VGJ.S vs OG 2018国际邀请赛淘汰赛BO3 第二场 8.22
2018/08/23 DOTA
[45:14]Optic vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
python SMTP实现发送带附件电子邮件
2018/05/22 Python
浅谈Django QuerySet对象(模型.objects)的常用方法
2020/03/28 Python
python数据处理——对pandas进行数据变频或插值实例
2020/04/22 Python
Python扫描端口的实现
2021/01/25 Python
is_file和file_exists效率比较
2021/03/14 PHP
新百伦折扣店:Joe’s New Balance Outlet
2016/08/20 全球购物
中国网上药店领导者:1药网
2017/02/16 全球购物
size?法国官网:英国伦敦的球鞋精品店
2020/03/15 全球购物
日本AOKI官方商城:AOKI西装
2020/06/11 全球购物
南京软件公司的.net程序员笔试题
2014/08/31 面试题
水利公司纪检监察自我鉴定
2014/02/25 职场文书
班主任对学生的评语
2014/04/26 职场文书
五水共治一句话承诺
2014/05/30 职场文书
2015年社区文体活动总结
2015/03/25 职场文书
Linux7.6二进制安装Mysql8.0.27详细操作步骤
2021/11/27 MySQL