javaScript之function定义

[size=x-large][color=blue]背景知识[/color][/size]

[color=green][b][url=http://lixh1986.iteye.com/blog/2028899]变量类型与变量声明[/url][/b][/color]

[color=green][b]函数定义[/b][/color]
在javaScript中,function的定义有 3 种:


//

// 1、匿名定义
function(){}

// 2、非匿名定义
function fn(){}

// 3、使用 Functon 对象定义
fn = new Function("some code");

// 这里说明一下:
// function 是一个关键字,而 Function 是一个对象。



[color=green][b]触发函数执行[/b][/color]
1、对于匿名函数:
(function(){})(); [color=green]//执行一个匿名函数[/color]
var f = function(){}(); [color=green]//执行一个匿名函数,并将匿名函数的返回值,赋值给f[/color]
!function(){}(); [color=green]//执行一个匿名函数[/color]

[color=olive]以上三种写法,
无非就是要把 匿名函数 作为一个表达式块 然后执行。[/color]


2、对于非匿名函数:
函数名(); [color=green]//如: fn();[/color]


[color=green][b]用法示例[/b][/color]
例子 1
function add(x, y){
return(x + y);
}
例子 2
var add = new Function("x", "y", "return(x+y)");

例子 3
var fn = function(){ }
将匿名函数的引用赋值给一个变量。(最常用的写法)如:

var add = function(x, y){
return(x + y);
}
----------------------------------------------------------------
可以用如下代码行调用以上函数:
add(2, 3);

[color=#555555]注意 : 在调用函数时,请确保包含了括号和必需的参数。调用函数时不用括号导致返回函数的文本而不是函数执行的结果。
add(2, 3);// return "5"
add; // renturn " function add(x, y){return(x + y);}[/color]


[b][color=blue]1、用法剖析[/color][/b]


<html>
<head>
<style type="text/css">
p{ background-color: #ada; height:40px; width:300px;line-height:40px;border-radius:10px;padding:0 20px;}
#myDiv{margin:auto;width:400px;background-color:#fefefe;}
body{padding-top:20px;}
</style>
</head>
<body>
<div id="myDiv">
<p>test_0</p>
<p>test_1</p>
<p>test_2</p>
<p>test_3</p>
<p>test_4</p>
<p>test_5</p>
</div>

<script type="text/javascript">

/********************Method 1********************************/

//常规的写法(正确的写法)
function method_1(){
var item=document.getElementsByTagName('p');
for(var i=0;i<item.length;i++){
item[i].onclick=(function(i){
return function(){
alert(i);
}
})(i);
}
}



/********************Method 2********************************/

//所有的 p 都 alert() 最后一个 i 的值(错误的写法)
function method_2(){
var item=document.getElementsByTagName('p');
for(var i=0;i<item.length;i++){
item[i].onclick=function(){
alert(i);
};
}
}
/*
说明:
item[i].onclick=(function(){})(); 匿名函数与立即执行 ,然后把结果给item[i].onclick
*/


/********************Method 3********************************/
//最能表达含义的写法(正确的写法)
function method_3(){
function createFunction(index){
return function(){
alert(index);
}
}

var elems = document.getElementsByTagName('p');
for(var i=0,len=elems.length; i<len; i++){
elems[i].onclick = createFunction(i);
}
}



/*说明:
* return function(){ alert(letter); }
* =
* return var fn = new Function(){ alert(letter);}
*
* 调用 function ,生成(定义)function.
* renturn 的 时候其实是 new 了一个function 出来。
*/

//===================================================================================
//run function.

//window.onload = method_3;
//or
window.onload = function(){
method_1();
}

</script>
</body>
</html>


注:关于 window.onload : [url=http://lixh1986.iteye.com/blog/2280574]Launching Code on Document Ready [/url]

[b][color=blue]2、运行效果图[/color][/b]

[img]http://dl2.iteye.com/upload/attachment/0089/6347/f9125558-f302-384d-9b1e-c45583a747ce.png[/img]


[b][color=blue]3、深入理解js的dom机制[/color][/b]


[b]js的一切对象(包括函数)都是依赖于 html的dom而存在的。[/b]

默认对象是window,所有的方法、属性,默认都是window对象的属性和方法
---------------------------
alert() = window.alert()
---------------------------
var x = window.x
var x = 10;
alert(window.x ); //10

[b]我们猜测所有js函数运行时的环境,也是基于某个对象的(该对象的属性就是其运行环境)。[/b]

请看下面的例子:

例子一
<html>
<head>
<style type="text/css">
p{
width:200px;
height:30px;
background-color:#F0F0F0;
}
</style>
</head>
<body>
<p>test </p>
<p>test </p>
<p>test </p>
<p>test </p>
<p>test </p>
<p>test </p>
<script type="text/javascript">
window.onload=function(){
var adiv=document.getElementsByTagName('p');
for(var i=0;i<adiv.length;i++){
adiv[i].onclick=function(){
alert(i);
}
}
}
</script>
</body>
</html>

结果:(无论点那个都alert 6)

[img]http://dl2.iteye.com/upload/attachment/0089/7698/aa5c2afb-45eb-3ec2-946d-3b6113b80cef.png[/img]


例子二
<html>
<head>
<style type="text/css">
p{
width:200px;
height:30px;
background-color:#F0F0F0;
}
</style>
</head>
<body>
<p>test </p>
<p>test </p>
<p>test </p>
<p>test </p>
<p>test </p>
<p>test </p>
<script type="text/javascript">
window.onload=function(){
var adiv=document.getElementsByTagName('p');
for(var i=0;i<adiv.length;i++){
adiv[i].onclick=(function(i){
return function(){ alert(i);};
})(i);
}
}
</script>
</body>
</html>

结果:(正常)

[img]http://dl2.iteye.com/upload/attachment/0089/7700/5d17c38f-c78e-37a5-a930-2ac223819963.png[/img]


[color=green]原因:[/color]

在例子二中,
改变了onclick事件的function的作用域范围。
(function(){
return fuction(){};
})();
新new了一个function作用域,赋值给onclick事件。


[color=green]分析:[/color]


例子一:
当onclick触发时,它实际(引用)运行的环境是 window.onload ,
window.onload是一个function,而它又有自己的属性:
window.onload.adiv
window.onload.i
window.onload.adiv[0].onclick
window.onload.adiv[1].onclick
window.onload.adiv[2].onclick
window.onload.adiv[3].onclick
...

onclick 会在当前作用域中找adiv(找到了) ,也会去找 i ,但是此时 i 的值 是 adiv.leng-1
所以会一直 alert 一个值


而如下方式(例子二):
window.οnlοad=function(){
var adiv=document.getElementsByTagName('p');
for(i=0;i<adiv.length;i++){
adiv[i].οnclick=(function(i){
return function(){alert(i)};
})(i);
}
}
}
是采用匿名函数立即执行,利用立即执行为匿名函数,window.onload为自身创建属性(一个匿名函数)
此匿名又有2个属性(一个参数i,一个funcion)
并把执行后的结果赋值给 adiv[i].onclick
此时window.onload的结构大致是:
window.onload.adiv
window.onload.i
window.onload.adiv[0].onclick
window.onload.(function(0){})
window.onload.(function(0){}).i
window.onload.(function(0){}).function

window.onload.adiv[1].onclick
window.onload.(function(1){})
window.onload.(function(1){}).i
window.onload.(function(1){}).function

...

赋值后
window.onload.adiv[0].onclick =
window.onload.(function(0){}).function

此时adiv[0].onclick的作用域是:window.onload.(function(0){})
不再是原来的:window.onload


在新的作用域中是有 i 的,而 i 的值,就是当初传进来的值。



再看下面的例子:
<html>
<head>
<style type="text/css"></style>
</head>
<body>
<script type="text/javascript">
/*
//1.
function Wen(){
this.name = "taobao";
this.waitMes=function(){
setTimeout(function(){this.fn(this.name);},1000);
};
this.fn=function(name){
alert(name);
}
}
var foo=new Wen();
foo.waitMes();

//**运行结果:空。
// *因为setTimeout 运行时的上下文环境是window
// *而 window 没有 fn 和 name 属性
//**故alert值为空

//2.
var name = "taobao";
function fn (name){
alert(name);
}
function Wen(){
this.waitMes=function(){
setTimeout(function(){this.fn(this.name);},1000);
};
}
var foo=new Wen();
foo.waitMes();

//**运行结果:非空。
// *将 fn 和 name 放在 window 对象下


//3.
function Wen(){
this.name = "taobao";
this.waitMes=function(){
var that = this;
setTimeout(function(){that.fn(that.name);},1000);
};
this.fn=function(name){
alert(name);
}
}
var foo=new Wen();
foo.waitMes();

//**运行结果:非空。
// *that作为参数传递到this中
*/

//4.
function Wen(){
this.name = "taobao";
this.waitMes=function(){
var that = this;
setTimeout(that.fn,1000);
};
this.fn=function(){
alert(this.name);
};

}
var foo=new Wen();
foo.waitMes();

//**运行结果:空。
// * this 仍然是指 window 对象。
// * 因为调用的是 window 对象的 setTimeout()方法。
// */

</script>
</body>
</html>





[b][color=blue]4、变量作用域之 变量覆盖[/color][/b]

[color=green]原理:[/color]
由于js function对象的 hoisting 特性(函数内的所有变量都相当于自动在函数头部声明,赋值部分位置不变),
可能会导致访问变量时出现 undefined。

例子:
 <script type="text/javascript">
//1.
var foo = 'This is foo.';
(function(){
alert(foo);//This is foo.
})();

//2.
var foo = 'This is foo.';
(function(){
alert(foo);//undefined
var foo = 2;
})();

/**
function对象的 hoisting 特性:函数内的所有变量都相当于自动在函数头部声明
故 2 等价于这种写法:

var foo = 'This is foo.';
(function(){
var foo;
alert(foo);
foo = 2;
})();

在2中,又定义了一个局部变量foo,(覆盖了上级范围的foo),但是没有给赋初值,
故访问foo时,出现 undefined 提示。
*/
</script>


[color=green]所以,在函数定义时,其所有用到的变量,要写在函数体前。[/color]


[color=green]补录:[/color]
---
匿名函数自动执行,只是一种简便的写法而已,并无新奇或创意。
(function(){})();
等价于
var fn = function(){};
fn();//执行
在任何使用过程中,完全可以用后一种方式替代。


—————————————

javascript 函数基础系列文章

[url=http://lixh1986.iteye.com/blog/1955314]1、JavaScript之变量的作用域[/url]
[url=http://lixh1986.iteye.com/blog/2028899]2、javascript之变量类型与变量声明及函数变量的运行机制[/url]
[url=http://lixh1986.iteye.com/blog/1947017]3、javaScript之function定义[/url]
[url=http://lixh1986.iteye.com/blog/1896682]4、javascript之function的prototype对象[/url]
[url=http://lixh1986.iteye.com/blog/1891833]5、javascript之function的(closure)闭包特性[/url]
[url=http://lixh1986.iteye.com/blog/1960343]6、javascript之function的this[/url]
[url=http://lixh1986.iteye.com/blog/1943409]7、javascript之function的apply(), call()[/url]


___________


javascript 面向对象编程系列文章:

[url=http://lixh1986.iteye.com/blog/1958956]1、javaScript之面向对象编程[/url]
[url=http://lixh1986.iteye.com/blog/2332467]2、javascript之面向对象编程之属性继承[/url]
[url=http://lixh1986.iteye.com/blog/2348442]3、javascript之面向对象编程之原型继承[/url]


-


-转载请注明出处:
http://lixh1986.iteye.com/blog/1947017


-
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值