Function类型
1.函数的创建
1.1 函数的声明
function sayHello(){
console.log("hello");
}
1.2 函数表达式
var say=function(){
console.log("hello");
}
2.函数属性和方法
ECMAScript中函数就是对象,因此函数也有属性和方法。
1.继承属性属性
1.length
length属性表示函数希望接纳的命名参数个数
function sayName(name){
console.log(name);
}
function sum(num1,num2){
return num1+num2;
}
function sayHi(){
console.log("hi");
}
conosle.log(sayName.length) //1
conosle.log(sum.length) //2
console.log(sayHi.length) //0
2.prototype
2.非继承的方法
apply()和call()真正用途是扩充函数赖以运行的作用域
1. apply()
该方法接受两个参数:一个是在其中运行 函数的作用域,另一个是参数数组。其中参数数组可以是数值或arguments对象(类数组对象)
function Person(name,age){
this.name=name;
this.age=age;
}
function Students(gender){
Person.apply(this,arguments);
this.gender=gender;
}
var stu= new Students("cc",12,'male');
console.log(stu); //{name:"cc",age:12,"male"};
**:当new 一个Students时,此时this 指向new,假设不用apply方法 直接使用 Person(arguments);此时Person中的this指向的是node 则两个this指向不同。则在各自环境里面增加属性。
2. call()
call和apply方法作用相同,区别在于接受参数的方式不同。对于call()方法来说,第一个参数this值没有变化,变化的是其余参数都是直接传递给函数。
function sum(num1,num2){
return num1+num2;
}
function callSum(num1,num2){
return sum.call(this,num1,num2);
}
console.log(callSum(10,12)); //22
3.函数调用
1. 函数名(实参)
sayHello("cc"); //函数声明会自动提升
function sayHello(name){
console.log("hello",name);
}
say(); //会报错
var say=function(){
console.log("hello");
}
**:解析器执行代码前,会将函数声明提升。因此即使调用放到 声明前也不会报错。但是在执行函数所有语句之前,变量 say中不会保存有对函数的引用,所以将函数调
用放到函数表达式前会报错。
2.函数的内部参数
只有在函数运行时才能被确定的参数
1.形式参数
2.arguments(类数组对象)
该对象有一个callee属性,该属性是一个指针,指向拥有这个arguments对象的函数,请看下面阶乘案例:
function factorial(num){
if(num<=1){
return 1;
}else{
return num * factorial(num-1);
}
}
——>如果此时改掉函数名的话,我们还得将引用函数名的地方都要改掉不然会报错。下面我们使用callee属性可以解决上述问题(在严格模式下,第5版 ECMAScript (ES5) 禁止使)
function factorial(num){
if(num<=1){
return 1;
}else{
return num * arguments.callee(num-1);
}
}
3.this
this引用的是函数执行的环境对象--或者说是this值(当在网页全局作用域中调用函数时,this对象引用的就是window;当在Node在运行时,用全局作用域调用函数则this指向node)
以下代码在node环境下运行:
global.a=4;
var a=3;
function say(){
var a=5;
console.log(this.a);
}
var obj={
a:2,
say:say
}
console.log(this); //{} 在浏览器中打印 window
say(); //4
obj.say() //2
**:当在全局环境下,直接输出this 则打印{}即空对象;若在浏览器中打印则输出window。当在函数中打印this,则指向执行它的对象。
4.函数的应用
1.函数作为返回值
我们不仅可以向传递参数一样把一个函数传递给另一个函数,而且可以将一个函数作为另一个函数的结果返回。
function callFunction(someFunction,arg){
return someFunction(arg);
}
function add(num){
return num+10;
}
var result=callFunction(add,10); //20
**:要返回一个函数的指针则在函数名后不能加'()';如果执行函数则要加'()'
案例:对数组对象排序
方法一:
/*
* 定义一个排序函数
* arg 要排序的参数
*/
function createPaixu(arg){
return function(obj1,obj2){
if(obj1[arg]<obj2[arg]){
return -1; //第一个值位于第二个值之前
}else if(obj1[arg]>obj2[arg]){
return 1;
}else{
return 0;
}
};
}
var data=[{name:"cc",age:12},{name:"wgs",age:33}];
var result=data.sort(createPaixu("age"));
console.log(result);
方法二:
var data=[{name:"cc",age:12},{name:"wgs",age:33}];
var result=data.sort((function(arg){
return function(obj1,obj2){
if(obj1[arg]<obj2[arg]){
return -1;
}else if(obj1[arg]>obj2[arg]){
return 1;
}else{
return 0;
}
};
})("age"));
console.log(result);
解释:这里创建了包含两个对象的数组data,在默认情况下,sort()方法排序会调用每个对象的toString()方法以确定他们的次序。因此得到的结果并非我们想要的。因此我们调用createPaixu("age")方法创建一个比较函数,对每个age属性值进行排序.方法二与方法一唯一区别就是将 排序函数写到sort里面,并自执行。
2. 函数式方程(lamda表达式,回调函数)
function dealData(handle){
var data={
name:"cc",
age:12
};
handle(data);
}
dealData(function(data){
console.log(JSON.stringify(data));
});