javaScript之function定义
背景知识
函数定义
在javaScript中,function的定义有3种:
1、匿名定义
function(){}
2、非匿名定义
function fn(){}
fn = new Function();
触发函数执行
对于匿名函数:
(function(){})(); //执行一个匿名函数
var f = function(){}(); //执行一个匿名函数,并将匿名函数的返回值,赋值给f
!function(){}(); //执行一个匿名函数
以上三种写法,
无非就是要把 匿名函数 作为一个表达式块 然后执行。
对于非匿名函数:
函数名(); //如: fn();
用法示例
例子 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);
注意 : 在调用函数时,请确保包含了括号和必需的参数。调用函数时不用括号导致返回函数的文本而不是函数执行的结果。
add(2, 3);// return "5"
add; // renturn " function add(x, y){return(x + y);}
1、用法剖析
- <html>
- <head>
- <style type="text/css">
- p{
- #CCCCCC;
- height:20px;
- width:100px;
- }
- </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">
- /********************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 的值(错误的写法)
- /*
- 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 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 出来。
- */
- </script>
- </body>
- </html>
2、运行效果图

3、深入理解js的dom机制
js的一切对象(包括函数)都是依赖于 html的dom而存在的。
默认对象是window,所有的方法、属性,默认都是window对象的属性和方法
---------------------------
alert() = window.alert()
---------------------------
var x = window.x
var x = 10;
alert(window.x ); //10
我们猜测所有js函数运行时的环境,也是基于某个对象的(该对象的属性就是其运行环境)。
请看下面的例子:
例子一
- <html>
- <head>
- <style type="text/css">
- p{
- width:200px;
- height:30px;
- }
- </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)

例子二
- <html>
- <head>
- <style type="text/css">
- p{
- width:200px;
- height:30px;
- }
- </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>
结果:(正常)

原因:
在例子二中,
改变了onclick事件的function的作用域范围。
(function(){
return fuction(){};
})();
新new了一个function作用域,赋值给onclick事件。
分析:
例子一:
当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.onload=function(){
var adiv=document.getElementsByTagName('p');
for(i=0;i<adiv.length;i++){
adiv[i].onclick=(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();
- //**运行结果:非空。
- // *that作为参数传递到this中
- </script>
- </body>
- </html>
4、变量作用域之 变量覆盖
原理:
由于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>
所以,在函数定义时,其所有用到的变量,要写在函数体前。
补录:
---
匿名函数自动执行,只是一种简便的写法而已,并无新奇或创意。
(function(){})();
等价于
var fn = function(){};
fn();//执行
在任何使用过程中,完全可以用后一种方式替代。
javaScript之function定义的更多相关文章
- JavaScript jQuery 中定义数组与操作及jquery数组操作
首先给大家介绍javascript jquery中定义数组与操作的相关知识,具体内容如下所示: 1.认识数组 数组就是某类数据的集合,数据类型可以是整型.字符串.甚至是对象Javascript不支持多 ...
- JavaScript笔记 Function
在JavaScript中方法由两部分组成: 方法名和方法体. JavaScript中的方法跟其他传统面向对象语言不同,它跟普通的变量没有区别,唯一不同点是它是Function对象,因此它会有一些Fun ...
- javascript函数的定义与执行
要理解javascript函数的定义与执行,首先需要知道这几个重要的概念,现在可以先知道稍后再理解! 函数的执行环境(excution context).活动对象(call object).作用域(s ...
- (转)深入理解javascript的function
原文:http://www.cnblogs.com/sharpxiajun/archive/2011/09/16/2179323.html javascript笔记:深入理解javascript的fu ...
- javascript的Function 和其 Arguments
http://shengren-wang.iteye.com/blog/1343256 javascript的Function属性:1.Arguments对象2.caller 对调用单前函数的Func ...
- JavaScript的function对象
我必须先说Java与JavaScript没有关系,不是我以前想的那个样子的(JavaScript是Java的一种超进化) 在JavaScript中,函数(function)就是对象. JavaScri ...
- Javascript函数(定义、传值、重载)
Javascript 函数的定义的方式有不止一种. 第一种方式: function fn1(){ alert(typeof fn1); alert(“fn1”); } 在调用的时候直接就可以fu1() ...
- JavaScript之Function函数深入总结
整理了JavaScript中函数Function的各种,感觉函数就是一大对象啊,各种知识点都能牵扯进来,不单单是 Function 这个本身原生的引用类型的各种用法,还包含执行环境,作用域,闭包,上下 ...
- JavaScript Nested Function 的时空和身份属性
JavaScript 的function 不仅仅是一等公民,简直就是特殊公民.它有许多独特的特征: 1) 它是object,可以存储,传递,附加属性. 2) 它可以有lexical closure, ...
随机推荐
- .NET中那些所谓的新语法
.NET中那些所谓的新语法之四:标准查询运算符与LINQ 摘要: 开篇:在上一篇中,我们了解了预定义委托与Lambda表达式等所谓的新语法,这一篇我们继续征程,看看标准查询运算符和LINQ.标准查询运 ...
- RCU介绍
RCU原理: RCU(Read-Copy Update),顾名思义就是读-拷贝修改,它是基于其原理命名的.对于被RCU保护的共享数据结构,读者不需要获得任何锁就可以访问它,但写者在访问它时首先拷贝一个 ...
- Linux时间子系统(六) POSIX timer
一.前言 在用户空间接口函数文档中,我们描述了和POSIX timer相关的操作,主要包括创建一个timer.设定timer.获取timer的状态.获取timer overrun的信息.删除timer ...
- android的一些控件
原来朋友给过的一个 显示时间的 样例,还能够改动时间,可是要机子有root权限才干改动. 在这个时间表盘的样例基础上 改动改动 图片.背景图什么的 就能够达到自己想要的效果了.. 下载地址 ...
- Litjson序列化
var jsonStr = JsonMapper.ToJson(tmpType); var tmpObject = JsonMapper.ToObject<TestClass>(jsonS ...
- paip.提升性能--多核编程中的java .net php c++最佳实践 v2.0 cah
paip.提升性能--多核编程中的java .net php c++最佳实践 v2.0 cah 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax ...
- kindle paperwhite3 连不上WIFI解决方法
确定能连接上其它的设备比如手机.如果是密码没错,路由器也正常,但是你还是连接不上,那就跟我之前遇到一样了.你先让你的kpw连接一次,不要动,再检查下你路由器连接的客户端列表(我的是在DHCP服务器一栏 ...
- 【Android】3.9 覆盖物功能
分类:C#.Android.VS2015.百度地图应用: 创建日期:2016-02-04 一.简介 百度地图SDK所提供的地图等级为3-19级(3.7.1版本中有些部分已经提供到了21级),所包含的信 ...
- 如何创建自己的ruby gem包
编写一个最简单的例子 1. 建好如下文件夹 注意:lib目录下必须有个和你gem名字一样的rb文件. $ cd hola $ tree . ├── hola.gemspec └── lib └── h ...
- Linux GCC编译库
本文主要解决以下几个问题 1).为什么要使用库? 2).库的分类 3).创建自己的库 为什么要使用库? 或许大家对自己初学 Linux时的情形仍记忆尤新吧.如果没有一个能较好的解决依赖关系的包管理器, ...