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

javascript中的函数Function

2015-08-31 10:28 549 查看
[1]三种函数定义的方式

[1.1]函数声明:使用function关键字,后跟一组参数以及函数体

[注意]函数的形参之间用逗号分割,因为是声明多个变量,不是多个语句,所以用逗号分隔,而不是分号

function sun(num1,num2){

  return num1+num2;

}

[1.2]函数表达式

var sum = function(num1,num2){

  return num1+num2

}

[1.3]Function构造函数

var sum = new Function('num1','num2','return num1 + num2');

//[不推荐]会导致解析两次代码,第一次解析常规ECMAScript代码,第二次解析传入构造函数中的字符串,影响性能

[tips]函数声明与函数表达式的区别:

[a1]解析器会率先读取函数声明,并使其在执行任何代码之前可用

[a2]至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行

如果将函数表达式放在对函数的引用语句之后,会弹出"unexpected identifier"意外标识符错误

[c]除了什么时候可以通过变量访问函数这一点区别之外,函数声明与函数表达式的语法其实是等价的

[b][2]函数参数


[2.1]函数参数在内部是用一个数组来表示的,在函数内部可以通过arguments对象来访问这个参数数组

[2.2]形参只提供便利,但不是必须的

[2.3]开发人员可以利用argument.length属性让函数能够接收任意个参数分别实现适当的功能

[2.4]没有传递值的形参默认为undefined

[2.5]函数参数也被当作变量来对待,因此其访问规则与执行环境中的其他变量相同

[2.6]arguments对象可以和形参一起使用,它的值与对应形参的值保持一致。但形参数组和arguments对象并不指向同一内存空间,它们的内存空间是独立的,但值会同步。

e.g. function doAdd(num1,num2){

  arguments[1] = 10;

  //[注意1]若未传入num2,num2 == undefined,并不会被赋值为10,而arguments[1] == 10

  //[注意2]若传入num2,则 num2 == arguments[1] == 10,二者都等于10

  //[注意3]在严格模式下,不允许为arguments赋值,但允许为arguments
赋值

  alert(arguments[0] + num2);

}

doAdd(1,2);//11

doAdd(1);//NaN 因为 1 + Number(undefined) == 1 + NaN == NaN

[2.7]所有参数传递的都是值,不可能通过引用传递参数

function setName(obj){
  obj.name = 'Nicholas';
  obj = new Object();
  obj.name = 'greg';
}
var person = new Object();
setName(person);
alert(person.name);//'Nicholas'


[tips]严格模式的限制

[a]不能把函数命名为eval或arguments

不能把函数参数命名为eval或arguments

[c]不能出现两个命名参数同名的情况

[b][3]函数返回值
:通过return语句后跟要返回的值来实现返回值,未指定返回值的函数则默认返回undefined

[注意]位于return语句之后的任何代码都永远不会执行

[4]函数重载:ECMAScript函数没有重载,不存在函数签名的特性,因为其函数参数是以一个包含零或多个值的数组的形式传递的。

[注意]通过检查传入函数中参数的类型和数量并作出不同的反应,可以模仿方法的重载。

[5]函数的属性

[5.1]this:引用的是函数据以执行的环境对象,当在网页全局作用域中调用函数时,this对象引用的是window

[注意]在严格模式下,未指定环境对象而调用函数,则this值不会转型为window,除非明确把函数添加到某个对象或者调用apply()或call(),否则this值将是undefined

[5.2]arguments:一个类数组对象,包含着传入函数中的所有参数

[5.2.1]arguments下有一个名为callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数

[注意]当函数在严格模式下运行时,访问arguments.callee会导致错误

[tips]阶乘函数

function factorial(num){
if(num <=1){
return 1;
}else{
return num* factorial(num-1);
}
}


若使用arguments.callee可以消除函数解耦

function factorial(num){
if(num <=1){
return 1;
}else{
return num* arguments.callee(num-1);
}
}


[5.3]length:表示函数希望接收的命名参数的个数

[5.4]prototype:在ECMAScript5中,prototype属性是不可枚举的,因此使用for-in无法发现

[5.5]caller(ECMAScript5):除了Opera的早期版本不支持,其他浏览器都支持ECMAScript3并没有定义的属性。这个属性保存着调用当前函数的函数的引用。如果是在全局作用域中调用当前函数,它的值为null

[注意1]ECMAScript5还定义了arguments.caller属性,在严格模式下访问它也会导致错误,而在非严格模式下这个属性始终是undefined,定义这个属性是为了分清arguments.caller和函数的caller属性

[注意2]严格模式还有一个限制:不能为函数的caller属性赋值,否则会导致错误

window.color = 'red';
var o = {color: 'blue'};
function sayColor(){
alert(this.color);
}
sayColor();//'red'
o.say = sayColor;
o.say();//'blue'


function outer(){
inner();
}
function inner(){
alert(inner.caller);
}
outer();//弹出function outer(){inner()};
//为了更松散的耦合,可以改为这样:
function outer(){
inner();
}
function inner(){
alert(arguments.callee.caller);
}
outer();


[6]函数的方法:apply和call这两个方法都是用于在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。最大的好处是对象不需要与方法有任何耦合关系,这两个方法的强大地方在于能够扩充函数的作用域。

[6.1]apply()方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组。第二个参数可以是Array()的实例,也可以是arguments对象。

[6.2]call()方法与apply()方法相同,区别仅仅在于接受参数的方式不同,在使用call()方法时,传递给函数的参数必须逐个列举出来,而apply方法接收arguments对象或一个数组

[6.3]bind()(ECMAScript5):创建一个函数的实例,其this值会被绑定到传给bind()函数的值

function sum(num1,num2){
return num1+num2;
}
function callSum1(num1,num2){
return sum.apply(this,arguments);
}
function callSum2(num1,num2){
return sum.apply(this,[num1,num2]);
}
function callSum00(num1,num2){
return sum.call(this,num1,num2);
}
function callSum01(num1,num2){
return sum.bind(this,num1,num2)();
}
alert(callSum00(10,10));//20
alert(callSum01(10,10));//20
alert(callSum1(10,10));//20
alert(callSum2(10,10));//20


var color = 'red';
var o = {color: 'blue'};
function sayColor(){
alert(this.color);
}
sayColor();//red
sayColor.call(this);//red
sayColor.apply(this);//red
sayColor.bind(this)();//red
sayColor.call(window);//red
sayColor.apply(window);//red
sayColor.bind(window)();//red
sayColor.call(o);//blue
sayColor.apply(o);//blue
sayColor.bind(o)();//blue


[7]继承的方法:始终返回函数代码(因浏览器而异,有的返回的代码与源代码中的函数代码一样。有的删除了注释并对某些代码做了改动)

  [a]toLocaleString()

  toString()

  [c]valueOf()

[b][8]函数的应用


[8.1]函数成为参数

function callSomeFunction(someFunction,someArgument){

  return someFunction(someArgument);

}

[8.2]从一个函数返回另一个函数

  [tips]根据属性名创建比较函数

function createComparisonFunction(propertyName){
return function (object1,object2){
var value1 = object1[propertyName];
var value2 = object2[propertyName];
if(value1 < value2){
return -1;
}else if(value1 > value2){
return 1;
}else{
return 0;
}
};
}


[8.3]为函数形参添加默认值

function G(id){
var id = id || 'div1';//为函数形参添加默认值来替代undefined
document.getElementById('id').innerHTML = '内容1'
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: