4.1 Function()对象概要
函数是代码语句的容器,可以使用圆括号操作符()来调用。调用函数时,参数可以在圆括号内传递,以使函数中的语句可以访问这些特定值。
var addNumberA = new Function('num1','num2','return num1+num2');
//var addNumberA = new Funtion('num1,num2','return num1+num2');
var addNumberB = function(num1,num2){
return num1+num2;
}
console.log(addNumberA(2,2));
console.log(addNumberB(2,2));
函数可用于返回值、构建对象,或者作为一种机制简单的运行代码。JavaScriot的函数有很多种用途,但从最基本的形式来说,函数只是可执行语句的唯一(一个?)作用域。
4.2 Function()参数
Function()构造函数采用不定数量的参数,但Function()构造函数的最后一个参数是一个包含具有函数体语句的字符串。在最后一个参数之前传递给构造函数的任何参数都可用于创建函数。也可以将多个参数放在一起以逗号分隔形成字符串进行传递。
! 不推荐或通常不直接利用Function()构造函数,因为JavaScript将使用evil()来解析包含数逻辑的字符串。很多人认为不必要使用eval(),因为如果要使用它,很有可能造成代码设计缺陷。
直接调用Function()构造函数是没有创建闭包
4.3 Function()属性和方法
属性
prototype
4.4 Function() 对象实例水属性和方法
实例属性
arguments
constructor
length
实例方法
apply()
call()
tiString()
4.5 函数总有返回值
由于可以创建一个函数以简单的执行代码语句,因此函数返回一个值也很常见。?
var sayHi = function()
{
return 'Hi';
}
console.log(sayHi());
(function(msg){console.log(msg);})('Hi');
console.log((function(msg){return msg;})('Hi'));
var no = function(){};
console.log(no());
4.6 函数是‘一等公民’(不仅语法,还有值)
在JavaScript中,函数是对象。这意味着函数可以存储在一个变量,数组或对象中。同时函数可以作为函数的参数传递给函数,并由函数返回。函数拥有属性,因为它是一个对象。
所有这些因素使函数在JavaScript中成为”一等公民“。
var funcA = function(){};
var funcB = [function(){}]; //调用方式:funcb[0],funcB的一个元素
var funcC = {method: function(){}}; //调用方式:funcC['method']() 或func.method()
*/
/*函数可以作为参数传递,也可以作为返回值返回*/
/*
var funcD = function(func)
{
return func;
};
var runFuncPassedToFuncD = funcD(function () {console.log('Hi')});
runFuncPassedToFuncD();
funcD.answer = 'yup';
console.log(funcD.answer);
至关重要的是,要意识到函数是一个对象,因此函数也是一个值。它可以像JavaScript中的其他表达式那样被传递或增加(属性and方法)。
4.7 函数de参数传递(不定参数)
在调用函数时,参数是将值传递给函数作用域的工具。
!
与其他编程语言相比,在JavaScript中省略参数是完全合法的,即使已经定义了解收这些参数的函数。只是为省略的参数赋予了undefined值。当然,省略参数后,函数有可能无法正常工作。
如果想函数传递意想不到的参数(那些在创建时没有被定义的参数),则不会发生任何错误。而且可以从arguments对象访问这些参数,arguments对象对所有函数都是可用的。
4.8 this和arguments适用于所有函数
在所有函数的作用域/函数体内,this和arguments值都是可用的。
arguments对象是一种类数组对象,它包含所有传递给函数的参数。即使在定义函数时不(未)指定的参数,在调用是还是发送参数,我们也可以依靠传递给函数的arguments数组来访问参数。(嗯,arguments对象是传递给函数的。)
var add = function(){
return arguments[0]+arguments[1];
}
console.log(add(4,5));
传递给所有函数的this关键字都是对包含函数的对象的引用。作为属性包含在对象内的函数(即方法),可以使用this来获得对”父”对象的引用。当函数在全局作用域中定义时,this值是全局对象。
var myObject1 = {
name: 'LiuYang',
method: function(){console.log(this)}
} //myObject1
var myObject2 = function(){console.log(this)}; //window
4.9 arguments.callee属性
arguments对象拥有名为callee的属性,它是对当前执行函数的引用。该属性可以用于从函数的作用域内引用函数(arguments.callee)–自我引用。
var foo = function foo(a,b,c,d,e){
console.log(arguments.callee); //foo
//callee可以用于对foo函数进行递归调用(例如:arguments.callee())
console.log(arguments.length);
console.log(foo.length);
}();
4.10 函数实例的length属性和argument.lenfth
arguments对象有一个独特的length属性,他给出的是在调用时发送给函数的参数数量(实参数量)。
通过使用Function()实例的length属性,实际上可以获得函数所需要的参数总数量(形参数量)。
!自JavaScript1.4开始,arguments.length属性就被废弃掉了,可以种函数对象的length属性获取发送给函数的参数数量。arguments.callee.length.
4,10 重定义函数参数
函数的参数可以直接在函数内部或通过arguments数组进行重新定义。
var foo = false;
var bar = false;
var myFunction = function (foo,bar){
console.log('1.',foo,bar);
arguments[0] = true;
bar = 2;
console.log('2.',foo,bar);
};
myFunction();
myFunction(true,true);
4.12 代码执行完前取消函数执行
return ...;
4.13 定义函数(语句、表达式或构造函数)
//函数语句
function addStatement(x,y){
return x+y;
} //!!!!!!!!!!没有分号!!!!!!!!!!!
//构造函数
var addConstructor = new Function('x,y','return x+y');
//函数表达式
var addExpression = function (x,y){
return x+y;
};
console.log(addConstructor(2,2),addStatement(2,2),addExpression(2,2));
4.14 调用函数call() and apply()
//调用函数之apply()和call()模式
var greet = {
runGreet: function () {
console.log(this.name,arguments[0],arguments[1]);
}
}
var cody = {name: 'liu'};
var lisa = {name: 'yang'};
//在cody对象上调用runGreet函数
greet.runGreet.call(cody,'foo','bar');
//在lisa对象上调用runGreet函数
greet.runGreet.apply(lisa,['foo','bar']);
注意call()和apply()之间的区别是函数调用时,参数传递的不同。前者传递的是过个分析额的参数;后者传递=多个参数组成的数组。
4.15 匿名函数
匿名函数主要用于将函数作为参数传递给另一个函数。
4.16 自调用的函数表达式
通过圆括号操作符,可以在定义函数表达式后立即调用该函数表达式(除了有Function()构造函数创建的函数)。
var sayWord = function sayHi (msg) {console.log(msg)}('hi');
4.17 自调用的匿名函数语句
(function(msg){return msg;})('Hi');
(function(msg){return msg;}('Hi'));
!function sayHi (msg) {console.log(msg)}('hi');
如果要立即调用函数,需要使用函数外面的圆括号(或任何将函数转换为表达式的符号)。
4.18 函数可以嵌套
函数嵌套的深度是没有限制的。
4.19 给函数传递参数,从函数返回函数
4.20 函数定义之前调用(函数提升)
在真正定义函数语句之前,可以在执行时调用该函数语句。
var speak = function()
{
say();
function say(){console.log('Yo')};
}();
console.log(sum(2,2));
function sum(x,y){return x+y};
上述原因发生的原因是,在运行代码之前,函数语句其实已经被编译器解释,并添加至执行堆栈/上下文。
!被定义为“函数表达式”的函数没有被提升—只有“函数语句”被提升。
4.21 函数可以调用自身(递归)