深入浅析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变量作用域更轻松
Oct 25 Javascript
jQuery选中select控件 无法设置selected的解决方法
Sep 01 Javascript
Webkit的跨域安全问题说明
Sep 13 Javascript
js对象的复制继承实例
Jan 10 Javascript
jQuery实现折线图的方法
Feb 28 Javascript
Javascript中的匿名函数与封装介绍
Mar 15 Javascript
详解Vue-基本标签和自定义控件
Mar 24 Javascript
vue实现nav导航栏的方法
Dec 13 Javascript
vue在自定义组件中使用v-model进行数据绑定的方法
Mar 25 Javascript
js实现简单分页导航栏效果
Jun 28 Javascript
使用vue-cli4.0快速搭建一个项目的方法步骤
Dec 04 Javascript
javascript局部自定义鼠标右键菜单
Dec 08 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在项目中寻找代码的坏味道(综艺命名)
2012/07/19 PHP
thinkphp数据查询和遍历数组实例
2014/11/28 PHP
php生成zip文件类实例
2015/04/07 PHP
网页的分页下标生成代码(PHP后端方法)
2016/02/03 PHP
实例讲解如何在PHP的Yii框架中进行错误和异常处理
2016/03/17 PHP
phpcms的分类名称和类别名称的调用
2017/01/05 PHP
centos下file_put_contents()无法写入文件的原因及解决方法
2017/04/01 PHP
非阻塞动态加载javascript广告实现代码
2010/11/17 Javascript
浅析js中取绝对值的2种方法
2013/07/09 Javascript
Javascript异步编程模型Promise模式详细介绍
2014/05/08 Javascript
纯JS代码实现一键分享功能
2016/04/20 Javascript
javascript数组常用方法汇总
2016/09/10 Javascript
js调用屏幕宽度的简单方法
2016/11/14 Javascript
JavaScript中从setTimeout与setInterval到AJAX异步
2017/02/13 Javascript
JavaScript实现的鼠标响应颜色渐变效果完整实例
2017/02/18 Javascript
ES6学习笔记之Set和Map数据结构详解
2017/04/07 Javascript
js控制文本框禁止输入特殊字符详解
2017/04/07 Javascript
ejsExcel模板在Vue.js项目中的实际运用
2018/01/27 Javascript
vue2中,根据list的id进入对应的详情页并修改title方法
2018/08/24 Javascript
微信小程序结合mock.js实现后台模拟及调试
2019/03/28 Javascript
seajs和requirejs模块化简单案例分析
2019/08/26 Javascript
vue计算属性+vue中class与style绑定(推荐)
2020/03/30 Javascript
[16:27]DOTA2 HEROS教学视频教你分分钟做大人-艾欧
2014/06/11 DOTA
python实现随机密码字典生成器示例
2014/04/09 Python
利用python操作SQLite数据库及文件操作详解
2017/09/22 Python
python使用threading获取线程函数返回值的实现方法
2017/11/15 Python
Python实现连接MySql数据库及增删改查操作详解
2019/04/16 Python
python 抓包保存为pcap文件并解析的实例
2019/07/23 Python
Python闭包装饰器使用方法汇总
2020/06/29 Python
python读取excel进行遍历/xlrd模块操作
2020/07/12 Python
Python3爬虫发送请求的知识点实例
2020/07/30 Python
pycharm 代码自动补全的实现方法(图文)
2020/09/18 Python
python openpyxl模块的使用详解
2021/02/25 Python
电信专业毕业生推荐信
2013/11/18 职场文书
学校政风行风自查自纠报告
2014/10/21 职场文书
详解PHP设计模式之依赖注入模式
2021/05/25 PHP