函数对象
- javascript中的函数就是对象。
- 每个函数对象在创建时也配有一个prototype属性。它的值是一个拥有constructor属性且值即为该函数的对象。
- 因为函数是对象,所以它们可以像任何其他的值一样被使用。函数可以保存在变量、对象和数组中。函数可以被当做参数传递给其他函数,函数也可以再返回函数。而且因为函数是对象,所以函数可以拥有方法。
- 函数的与众不同之处在于,它们可以被调用。
函数字面量
var add = function (a,b){
return a + b ;
}
加粗部分为函数字面量。
函数字面量可以出现在任何允许表达式出现的地方。一个内部函数除了可以访问自己的参数和变量,同时它也能自由访问把它嵌套在其中的福函数的参数与变量。通过函数字面量创建的函数对象包含一个连接到外部上下文的连接。这被称为闭包(closure)。它是js强大表现力的来源。
调用(this)
调用一个函数会暂停当前函数的执行,传递控制权和参数给新函数。除了声明时所定义的形式参数,每个函数还要接受两个附加参数:this和arguments。参数this的值取决于调用的模式。在js中一共有四种调用模式:方法调用模式、函数调用模式、构造器调用模式和apply调用模式。这些模式在如何初始化this上存在差异。
- 调用运算符是跟在任何产生一个函数值的表达式之后的一对圆括号。当实际参数(arguments)的个数与形式参数(parameters)的个数不匹配时,不会导致运行时错误。若实际参数值过多了,超出的参数值会被忽略。若参数值过少,则缺失的值会被替换为undefined。对参数值不会进行类型检查,任何类型的值都可以被传递给任何参数。
方法调用模式
当一个函数被保存为对象的一个属性时,我们称它为一个方法。当一个方法被调用时,this被绑定到该对象。若调用表达式包含一个提取属性的动作(.或[‘subscript’]下标表达式),那么它就是被当做一个方法来调用。
var myObject ={
value :0,
increment:function (inc){
this.value +=typeof inc === 'number'?inc:1;
}
};
myObject.increment();
document.writeln(myObject.value)//1
myObject.increment(2);
document.writeln(myObject.value)//3
方法可以使用this访问自己所属的对象,所以它能从对象中取值或对对象进行修改。this到对象的绑定发生在调用的时候。这个“超级延迟”绑定(very late binding)使得函数可以对this高度复用。通过this可去的它们所属对象的上下文的方法称为公共方法(public method)
函数调用模式
当一个函数并非一个对象的属性时,那么它就是被当做一个函数来调用的。
var sum = add(3 , 4 )//sum的值为7
以此模式调用函数时,this被绑定到全局对象。
//给myObject增加一个double方法
myObject.double = function(){
var that = this;//解决办法
var helper = function (){
that.value = add(that.value , that.value)
}
helper();//以函数形式调用helper
}
//以方法形式调用double
myObject.double();
document.writeln(myObject.value);//6
构造器调用模式
若一个函数前面带上new来调用,那么背地里将会创建一个连接到该函数的prototype成员的新对象,同时this会被绑定到那个新对象上。
new前缀也会改变return语句的行为。
//构造一个包含status成员的对象
var statusObject = {
status:"a-ok"
}
//statusObject并没有继承自Quo.prototype,但我们可以在statusObject上调用
//get_status方法,尽管statusObject并没有一个名为get_status的方法
var status =Quo.prototype.get_status.apply(statusObject)//status值为a-ok
console.log(status)
参数
当函数被调用时,会得到一个“免费”配送的参数,那就是arguments数组。函数可以通过此参数访问所有它被调用时传递给他的参数列表,包括多余参数。这使得编写一个无需指定参数个数的函数称为可能。
var sum = function(){
var i, sum =0;
for(i=0; i<arguments.length;i++){
sum+=arguments[i];
}
return sum;
}
console.log(sum(1,2,3,4,5,6,7))
arguments并非真正的数组。它只是一个类似数组(array like)的对象。arguments拥有一个length属性,但它没有任何数组的方法。
返回
一个函数总是会返回一个值。如果没有指定返回值,则返回undefined。
如果函数调用时在前面加上了new前缀,且返回值不是一个对象,则返回this(该新对象)。
扩充类型的功能
Function.prototype.method = function(name,func) {
// body...
this.prototype[name]=func
};
console.log(Number.__proto__)//Function
Number.method('integer',function(){
console.log(this)
return Math[this <0 ? 'ceil' : 'floor'](this)
})
String.method('trim',function(){
return this.replace(/^\s+|\s+$/g,'')
})
console.log((-10/3).integer())
递归
function hanuo(n,from, dep,to){//disc 1 is the biggest disc
if(n>0){
hanuo(n-1,from,to,dep)//move the top n-1 dics from 'from' to 'dep'
console.log("move disc no."+n+" from "+from+" to "+to)
hanuo(n-1,dep,from,to) //move that n-1 dics from 'dep' to 'src'
}
}
hanuo(3,"A","B","C")
//参考http://blog.csdn.net/kkkkkxiaofei/article/details/8333644/
模块
String.method('ide',function(){
var entity ={
quot:'"',
lt: "<",
ge:">"
};
return function(){
return this.replace(/&([^&;]+);/g,
function(a,b){
console.log("a",a)
console.log("b",b)
var r =entity[b];
return typeof r ==="string" ?r:a;
}
);
}
}())
console.log('<"'.ide())