JavaScript高级程序设计学习笔记——引用类型2Function类型(重要)
2016-01-29 11:39
746 查看
函数是Function类型的实例,所以函数也是对象,从而函数也拥有方法,可用来增强其行为。(这一点正是JS最有特色的地方)
函数名实际上是一个指向函数对象的指针,不会与某个函数绑定。
function sum(num1, num2){
return num1 + num2;
}//使用不带圆括号的函数名是访问函数指针,并非调用函数;
函数表达式:
var sum = function(num1, num2){
return num1 + num2;
};//注意:函数末尾有分号,就像声明其它变量一样;通过变量sum即可调用函数;
Function构造函数:
var sum = new Function("num1" , "num2" , " return
num1 + num2");//不推荐;前面是参数,最后是函数体;
当声明了多个同名函数时,后面的函数覆盖前面的函数,没有重载发生,主要是因为ECMAScript没有函数签名。
区分函数声明和函数表达式:解析器优先读取函数声明,并使其在执行任何代码之前可用(可访问);函数表达式,必须等到解析器执行到它所在的代码行才被执行,除了什么时候可以通过变量访问函数这点区别外,二者没有区别。当使用函数声明的形式来定义函数时,可将调用语句写在函数声明之前,而后者,这样做的话会报错。
函数名本身即为变量,所以函数可以作为值来使用,可将一个函数作为参数传递给另一个函数(函数作为参数时后面不可加括号),也可将一个函数作为另一个函数的返回值。
arguments是一个类数组对象,包含着传入函数中的所有参数。该对象有一个名为callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。
this,引用的是函数据以执行的环境对象。
ECMAScript5规范了另一个函数对象的属性:caller,该属性中保存着调用当前函数的函数引用,如果是在全局作用域中调用当前函数,该值为null。
length属性表示函数希望接收的命名参数的个数;
prototype属性时保存所有实例方法,该属性不可枚举,因此无法用for-in实现;诸如toString()、valueOf()等方法均保存在prototype名下,只不过是通过各自对象的实例访问;
每个函数还包括两个非继承而来的方法:apply()、call()。
二者的用途都是在特定作用域中调用函数,实际上等于设置函数体内的this对象值;
apply()接收两个参数:在其中运行函数的作用域,另一个是参数数组;
call()接收两个参数:在其中运行函数的作用域,另一个是传递给函数的参数逐个列出;
二者最强大的用途是可以扩充函数赖以运行的作用域,且对象不需要与方法有任何耦合关系:
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
sayColor(); //red
sayColor.call(this); //red
sayColor.call(window); //red
sayColor.call(o); //blue
bind()是ECMAScript5定义的,创建一个函数的实例,其this值会被绑定到传给bind()函数的值
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue
与在 Java 中一样,函数在执行过 return 语句后立即停止代码。因此,return 语句后的代码都不会被执行。
如果函数无返回值,那么可以调用没有参数的 return 运算符,随时退出函数。它真正返回的值是 undefined。
( function(){…} )()和( function (){…} () )是两种javascript立即执行函数的常见写法。
匿名函数适合用来定义再整个脚本里只出现一次的函数:匿名函数没有名字,只能在哪里定义,在哪里使用。
方式1,调用函数,得到返回值。强制运算符使函数调用执行
方式2,调用函数,得到返回值。强制函数直接量执行再返回一个引用,引用再去调用执行
这种方式也是很多库爱用的调用方式,如jQuery,Mootools。
方式3,使用void
方式4,使用-/+运算符
方式5,使用波浪符(~)
方式6,匿名函数执行放在中括号内
方式7,匿名函数前加typeof
方式8,匿名函数前加delete
deletefunction(){
console.log(this) // 浏览器得控制台输出window
}(this)
方式9,匿名函数前加void
方式10,使用new方式,传参
方式11,使用new,不传参
方式12,逗号运算符
方式13,按位异或运算符
方式14,比较运算符
最后看看错误的调用方式
函数名实际上是一个指向函数对象的指针,不会与某个函数绑定。
一、函数的定义
函数声明语法:function sum(num1, num2){
return num1 + num2;
}//使用不带圆括号的函数名是访问函数指针,并非调用函数;
函数表达式:
var sum = function(num1, num2){
return num1 + num2;
};//注意:函数末尾有分号,就像声明其它变量一样;通过变量sum即可调用函数;
Function构造函数:
var sum = new Function("num1" , "num2" , " return
num1 + num2");//不推荐;前面是参数,最后是函数体;
当声明了多个同名函数时,后面的函数覆盖前面的函数,没有重载发生,主要是因为ECMAScript没有函数签名。
区分函数声明和函数表达式:解析器优先读取函数声明,并使其在执行任何代码之前可用(可访问);函数表达式,必须等到解析器执行到它所在的代码行才被执行,除了什么时候可以通过变量访问函数这点区别外,二者没有区别。当使用函数声明的形式来定义函数时,可将调用语句写在函数声明之前,而后者,这样做的话会报错。
函数名本身即为变量,所以函数可以作为值来使用,可将一个函数作为参数传递给另一个函数(函数作为参数时后面不可加括号),也可将一个函数作为另一个函数的返回值。
二、函数内部属性
函数内部有两个特殊对象:arguments和this。arguments是一个类数组对象,包含着传入函数中的所有参数。该对象有一个名为callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。
function factorial(num){//阶乘函数 if(num <=1){ return 1; }else { return num * arguments.callee(num-1);//这样将函数的执行与函数名解耦合; } }
this,引用的是函数据以执行的环境对象。
window.color = "red"; var o = { color: "blue" }; function sayColor(){ alert(this.color); } sayColor(); //red o.sayColor = sayColor; o.sayColor(); //blue
ECMAScript5规范了另一个函数对象的属性:caller,该属性中保存着调用当前函数的函数引用,如果是在全局作用域中调用当前函数,该值为null。
function outer(){ inner(); } function inner(){ alert(arguments.callee.caller); } outer();//最后显示outer()函数的源代码,但要注意,不能为函数的caller属性赋值,否则导致错误
三、函数属性和方法
函数是对象,因此也具有属性和方法,每个函数都包含两个属性:length和prototype。length属性表示函数希望接收的命名参数的个数;
prototype属性时保存所有实例方法,该属性不可枚举,因此无法用for-in实现;诸如toString()、valueOf()等方法均保存在prototype名下,只不过是通过各自对象的实例访问;
每个函数还包括两个非继承而来的方法:apply()、call()。
二者的用途都是在特定作用域中调用函数,实际上等于设置函数体内的this对象值;
apply()接收两个参数:在其中运行函数的作用域,另一个是参数数组;
call()接收两个参数:在其中运行函数的作用域,另一个是传递给函数的参数逐个列出;
二者最强大的用途是可以扩充函数赖以运行的作用域,且对象不需要与方法有任何耦合关系:
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
sayColor(); //red
sayColor.call(this); //red
sayColor.call(window); //red
sayColor.call(o); //blue
bind()是ECMAScript5定义的,创建一个函数的实例,其this值会被绑定到传给bind()函数的值
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue
四、函数返回值
即使函数确实有值,也不必明确地声明它。该函数只需要使用 return 运算符后跟要返回的值即可。与在 Java 中一样,函数在执行过 return 语句后立即停止代码。因此,return 语句后的代码都不会被执行。
如果函数无返回值,那么可以调用没有参数的 return 运算符,随时退出函数。它真正返回的值是 undefined。
五、函数的执行
( function(){…} )()和( function (){…} () )是两种javascript立即执行函数的常见写法。
匿名函数适合用来定义再整个脚本里只出现一次的函数:匿名函数没有名字,只能在哪里定义,在哪里使用。
方式1,调用函数,得到返回值。强制运算符使函数调用执行
(function(x,y){ alert(x+y); returnx+y; }(3,4));
方式2,调用函数,得到返回值。强制函数直接量执行再返回一个引用,引用再去调用执行
(function(x,y){ alert(x+y); returnx+y; })(3,4);
这种方式也是很多库爱用的调用方式,如jQuery,Mootools。
方式3,使用void
void function(x) { x = x-1; alert(x); }(9);
方式4,使用-/+运算符
-function(x,y){ alert(x+y); returnx+y; }(3,4); +function(x,y){ alert(x+y); returnx+y; }(3,4); --function(x,y){ alert(x+y); returnx+y; }(3,4); ++function(x,y){ alert(x+y); returnx+y; }(3,4);
方式5,使用波浪符(~)
~function(x, y) { alert(x+y); returnx+y; }(3, 4);
方式6,匿名函数执行放在中括号内
[function(){ console.log(this) // 浏览器得控制台输出window }(this)]
方式7,匿名函数前加typeof
typeoffunction(){ console.log(this) // 浏览器得控制台输出window }(this)
方式8,匿名函数前加delete
deletefunction(){
console.log(this) // 浏览器得控制台输出window
}(this)
方式9,匿名函数前加void
void function(){ console.log(this) // 浏览器得控制台输出window }(this)
方式10,使用new方式,传参
newfunction(win){ console.log(win) // window }(this)
方式11,使用new,不传参
newfunction(){ console.log(this) // 这里的this就不是window了 }
方式12,逗号运算符
1, function(){ console.log(this) // window }();
方式13,按位异或运算符
1^function(){ console.log(this) // window }();
方式14,比较运算符
1>function(){ console.log(this) // window }();
最后看看错误的调用方式
function(x,y){ alert(x+y); returnx+y; }(3,4);
相关文章推荐
- CommonJS与AMD
- Extjs String转Json
- Javascript模块化编程(一):模块的写法
- 使用js实现“别踩白块儿”游戏
- html+js图片上传预览
- javaScript 与OC方法的调用
- js倒计时
- 动态创建按钮的JavaScript代码
- JavaScript面向对象初探——原型链、封装和继承
- js数值使用及数组转json,转化后的json传入后台解析
- 根据iPhone6设计稿动态计算rem值
- 使用js实现tab选项卡效果
- js动态创建按钮
- ArcGIS api for javascript加载shapefile
- 第 1 章 简单认识 JavaScript
- Javascript之基本包装类型
- JSP引入资源
- 比较两个json是否相等,忽略数组内元素顺序
- [JavaScript]JS+MySQL获取京东省市区地区
- Hibernate POJO在序列化(JSON)时遇到的若干问题