2014年11月10日
1,JavaScript函数具有两个特点: 函数是第一类对象 函数可以提供作用域
函数即对象,表现为:
-1,函数可以在运行时动态创建,也可以在程序执行过程中创建。
-2,函数可以分配给变量,可以将它们的引用复制到其他变量,可以被扩展,此外,函数还可以被删除。
-3,可以做为参数传递给其他函数,,还可以由其他函数返回。
-4,函数可以有自己的属性和方法。
2,声明VS表达式:名称和变量声明提升
//这是一个函数表达式
//它做为一个参数传递给函数 CallMe
callMe(function(){
//这是命名函数表达式
//也被称作匿名函数
});
//这是命名函数表达式
callMe(function me(){
//这里是命名函数表达式
//并且其名称为me
});
//另一个函数表达式
var myobject = {
say:function(){
//这里是函数表达式
}
};
3,函数的提升
对于所有的变量,不管在函数体的何处声明,都会在后台被提升到函数顶部。
4,回调模式
<script>
function writeCode(callBack){
console.log("callBanck before.....");
callBack();
console.log("callBanck after.....");
}
function callBack(){
console.log("callBanck ..........");
}
writeCode(callBack);
</script>
//输出结果callBanck before..... test1.html:14callBanck .......... test1.html:21 callBanck after.....
如下,展示了一个复杂的查询DOM节点,然后再在回调函数中依次进行业务处理。
耗时为2n
<script>
//查找节点
var findNodes = function(){
var i = 100000,//复杂循环
nodes[],//存储本次运行结果
found;//零时存储找到的节点
while(i){
//业务逻辑处理
//....
found = 1;
i -= 1;
nodes.push(found);
}
return nodes;
};
//对节点处理
var hide = function(nodes){
var i = 0, max = nodes.length;
for(; i < max; i += 1){
//复杂业务逻辑处理
console.log(nodes[i]);
}
};
//执行函数
hide(findNodes());
</script>
<script>
var findNodes = function(callBack){
var i = 10000,
nodes = [],
dound;
//检查回调函数是否为可调用
if(typeof callBack != "function"){
callBack = false;
}
while(i){
i -= 1;
//逻辑处理 。。。。。。。。
//运行回调函数
if(callBack){
callBack(found);
}
nodes.push[found];
}
return nodes;
};
var hide = function(node){
//对node节点进行对应的业务处理
};
findNodes(hide);
</script>
5,闭包
闭包特性,简而言之就是作用域。
6,自定义函数
-1,如果一个函数重新定义,则会覆盖原有函数。
var scareMe = function(){
console.log("FIRST!");
scareMe = function(){
console.log("SECOND!");
};
};
scareMe();scareMe();输出结果:日志: FIRST! 日志: SECOND!
该模式的确定是,当他重定义自身时,已经添加到原始函数的任何属性都会丢失。此外,如果该函数使用了不同的名称,比如分配给不同的变量或者以对象的方法来使用,那么重定义的部分将永远不会发生,并且将会只i系那个原始函数体。
<script>
var scareMe = function(){
console.log("FIRST!");
scareMe = function(){
console.log("SECOND!");
};
};
//添加新的属性
scareMe.property = "property";
//赋值给另一个不同名称的变量
var prank = scareMe;
//在一个方法里使用
var spooky = {
boo: scareMe
};
prank();// first
prank();//first
console.log(prank.property);//property
spooky.boo();//first
spooky.boo();//first
console.log(spooky.boo.property);//property
//使用自定义函数
scareMe();//second
scareMe();//second
console.log(scareMe.property);//undefined
</script>
输出结果:FIRST! test5.html:14 property test5.html:332FIRST! test5.html:14 property test5.html:372SECOND! test5.html:17 undefined
7,即时函数
即时函数,定义函数后立即执行该函数的语法。例子如下:
(function(){
alert("One");
}());
该模式由以下部分组成:
-1,可以使用函数表达式定义一个函数。
-2,在末尾添加一组括号,这将导致该函数立即执行。
-3,将整个函数包装在括号中。
该模式一般用于初始化时候,执行一些页面加载的任务。在初始化完成后就不需要这些变量。可以完全替代以全局变量形式创建的代码。如下代码就不会创建过多的全局变量。
<script>
(function(){
var days = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'],
today = new Date(),
msg = "Today is " + days[today.getDay()] + "," + today.getDate();
alert(msg);
}());
</script>
即时函数的参数
(function(who, how){
console.log("i'm " + who + ",I'm " + how);
}("pengke", "shabi"));
即时函数的返回值,如下代码,result指向函数的返回值4。
var result = (function(){
return 2 +2 ;
})();
8,函数属性——备忘模式
可以对函数的参数进行缓存处理
9,配置对象
适用于一个方法,我们不确定它有多少个参数的情况。
-1,不需要记住众多的参数以及其顺序。
-2,可以安全忽略可选参数
-3,更加易于阅读和维护
-4,更加易于添加和删除参数
<script> function addPerson(conf){ console.log(conf.first); console.log(conf.second); console.log(conf); } var conf = {first: "abc", second: "a", third: "c"}; addPerson(conf); </script>
10,函数应用
可以使用方法Function.prototype.apply().
<script>
//定义函数
var sayHi = function(who){
console.log("Hello " + (who ? "," + who : "") + "!");
};
sayHi();
sayHi('world');
sayHi.apply(null, ["world"]);
</script>
执行结果
Hello ! test10.html:15
Hello ,world! test10.html:15
Hello ,world!
apply第一个参数制定该函数内部的this。
当传递函数对应的时候,第一个参数不能为空,必须为函数名称。
11,Curry化
<script>
//curry化的add函数
function add(x, y){
var oldx = x, oldy = y;
if(typeof oldy == "undefined"){
return function(newy){
console.log(oldx + newy);
};
}
console.log(x + y);
}
console.log(typeof add(5));//function
add(3)(4);//7
var add2000 = add(2000);
add2000(10);//2010
</script>