您的位置:首页 > Web前端 > JavaScript

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和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);

这种方式也是很多库爱用的调用方式,如jQueryMootools

方式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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: