- 函数是对象。
js中的对象是‘名/值’对的集合并拥有一个连到原型对象的隐藏链接。
每个函数创建的时候,都会附加两个隐藏属性:函数的上下文和实现函数行为的代码。
函数是对象,可以跟其他值一样被使用。可以被保存在变量中、对象中、数组中。也可以作为参数传递给其他参数,或者作为返回值。当然也可以被定义在函数中。一个内部函数不仅可以自由地访问其内部的变量和参数,还可以自由地访问把它嵌套的父函数的变量和参数。这被称为闭包。 - 函数的字面量包括四个部分:
保留字:function;
函数名:用来递归调用自己。也可以省略,则为匿名函数;
包围在圆括号中的参数:多个参数用逗号分隔
包围在花括号中的一组语句:函数的主体,函数被调用的时候执行 - 函数的调用:函数名(参数)。除了声明时定义的形式参数,每个函数还会收到两个附加参数:this和arguments。这个this指向跟调用模式有关。
- 函数调用的四种模式:
1)、方法调用模式:当函数被保存为对象的一个属性的时候,我们称它为一个方法。使用.或者[]调用,this被绑定到该对象上。
var person={
name:'zhangsan',
walk:function(){
//此处this被绑定在person上,this.name就是'zhangsan'
console.log(this.name+' is walking');
}
}
person.walk();//zhangsan is walking
2)、函数调用模式:当一个函数并非一个对象的属性的时候,我们就把它当作一个函数来调用。此时的this指向全局对象。这是语言设计上的错误。如果设计正确,this应该仍然绑定到外部函数的this变量。解决办法是使用一个封闭的变量来存储this。(之后的es6语法中的箭头函数会解决该this指向问题,箭头函数无this指向,继承其父??)
var myObj={
value:0,
increment:function(inc){
this.value+=inc?inc:1;
}
}
myObj.add=function(){
var that =this;
function m(){
that.increment(5);
}
m();
}
myObj.add();
console.log(myObj.value);//5
3)、构造器函数模式
一个函数如果创建的时候就希望结合new 前缀来调用,那它就是构造器函数。约定:保存在以大写格式命名的变量里。此时this被绑定到new出来的实例对象,这个new出来的新对象已连接到该函数的prototype上。
function Person(){
this.age=12;
}
Person.prototype.grow=function(){this.age++;}
var p=new Person();
p.grow();
p.age;//13
4)、apply调用模式
因为函数也是对象,所以函数也有自己的方法。比如apply。使用apply可以指定this的值。
var computer={
base:0,
add:function(a){
var f=function(v){return this.base+v;}
return f(a);
},
addCall:function(b){
var f=function(v){return this.base+v;}
var o={base:2}
return f.call(o,b)
}
}
console.log(computer.add(1));//NaN 因为此时f函数中this指向全局
console.log(computer.addCall(2));
5、可以通过给Function.prototype来给所有函数添加方法。
Function.prototype.method=function(name,func){
this.prototype[name]=func;
return this;
}
// 给Number添加一个integer方法(其实这个我不懂,怎么到下面就不要Number.prototype了?还有为嘛加(this)?求大神指教)
Number.method('integer',function(){
return Math[this<0?'ceil':'floor'](this);
});
6、函数的作用域
在编程中,作用于控制着变量和参数的可见性和生命周期。帮助程序员减少变量名的冲突和提供自动内存管理。
js存在函数作用域。
7、闭包
定义在内部的函数可以访问定义在它外部的参数和变量。
内部函数比外部函数拥有更长的生命周期。
8、模块、级联、柯里化等后续更新