一、函数声明、函数表达式、匿名函数
1.函数声明:function fnName () {…};
使用function关键字声明一个函数,再指定一个函数名,叫函数声明。

2.函数表达式 var fnName = function () {…};
使用function关键字声明一个函数,但未给函数命名,最后将匿名函数赋予一个变量,叫函数表达式,这是最常见的函数表达式语法形式。

3.匿名函数:function () {}; 使用function关键字声明一个函数,但未给函数命名,所以叫匿名函数,匿名函数属于函数表达式,匿名函数有很多作用,赋予一个变量则创建函数,赋予一个事件则成为事件处理程序或创建闭包等等。

二、函数声明和函数表达式不同之处:
1.Javascript引擎在解析javascript代码时会‘函数声明提升',(Function declaration Hoisting)当前执行环境(作用域)上的函数声明,而函数表达式必须等到Javascirtp引擎执行到它所在行时,才会从上而下一行一行地解析函数表达式。
2.函数表达式后面可以加括号立即调用该函数,函数声明不可以,只能以fnName()形式调用 。以下是例子。

fnName();
function fnName(){
...
}
//正常,因为‘提升'了函数声明,函数调用可在函数声明之前 fnName();
var fnName=function(){
...
}
//报错,变量fnName还未保存对函数的引用,函数调用必须在函数表达式之后 var fnName=function(){
alert('Hello World');
}();
//函数表达式后面加括号,当javascript引擎解析到此处时能立即调用函数 function fnName(){
alert('Hello World');
}();
//不会报错,但是javascript引擎只解析函数声明,忽略后面的括号,函数声明不会被调用
function(){
console.log('Hello World');
}();
//语法错误,虽然匿名函数属于函数表达式,但是未进行赋值操作,
//所以javascript引擎将开头的function关键字当做函数声明,报错:要求需要一个函数名

三、立即运行的匿名函数(也叫立即调用函数):
( function(){…} )()
( function (){…} () )

1.在函数体后面加括号就能立即调用,则这个函数必须是函数表达式,不能是函数声明。

(function(a){
console.log(a); //firebug输出123,使用()运算符
})(123); (function(a){
console.log(a); //firebug输出1234,使用()运算符
}(1234)); !function(a){
console.log(a); //firebug输出12345,使用!运算符
}(12345); +function(a){
console.log(a); //firebug输出123456,使用+运算符
}(123456); -function(a){
console.log(a); //firebug输出1234567,使用-运算符
}(1234567); var fn=function(a){
console.log(a); //firebug输出12345678,使用=运算符
}(12345678)

可以看到输出结果,在function前面加!、+、 -甚至是逗号等
都可以起到函数定义后立即执行的效果,而()、!、+、-、=等运算符,都将函数声明转换成函数表达式,消除了javascript引擎识别函数表达式和函数声明的歧义,告诉javascript引擎这是一个函数表达式,不是函数声明,可以在后面加括号,并立即执行函数的代码。
加括号是最安全的做法,因为!、+、-等运算符还会和函数的返回值进行运算,有时造成不必要的麻烦。

2.不过这样的写法有什么用呢?
javascript中没用私有作用域的概念,如果在多人开发的项目上,你在全局或局部作用域中声明了一些变量,可能会被其他人不小心用同名的变量给覆盖掉,根据javascript函数作用域链的特性,可以使用这种技术可以模仿一个私有作用域,用匿名函数作为一个“容器”,“容器”内部可以访问外部的变量,而外部环境不能访问“容器”内部的变量,所以( function(){…} )()内部定义的变量不会和外部的变量发生冲突,俗称“匿名包裹器”或“命名空间”。

JQuery使用的就是这种方法,将JQuery代码包裹在( function (window,undefined){…jquery代码…} (window)中,在全局作用域中调用JQuery代码时,可以达到保护JQuery内部变量的作用。

3.(function(){}()) 和 (function(){})() 的区别:
(function(){}()) //直接执行匿名函数,无法传参
(function(){})() //先定义匿名函数再调用执行,可传入参数

(function(){})(); 是 把函数当作表达式解析,然后执行解析后的函数
相当于 var a = function(){}; a(); a得到的是函数

(function(){}()); 是把函数表达式和执行当作语句直接执行、
相当于 var a = function(){}(); a得到的是结果
最终结果是一样的、()只是起了 自执行的作用.

四、(function($){...})(jQuery)是什么意思?
匿名函数,调用函数时,是在函数后面写上括号和实参的,由于操作符的优先级,函数本身也需要用括号,即:
(function(arg){...})(param)
这就相当于定义了一个参数为arg的匿名函数,并且将param作为参数来调用这个匿名函数.

而(function($){...}) (jQuery)
则是一样的,之所以只在形参使用$,是为了不与其他库冲突,所以实参用jQuery,在所有DOM元素加载之前执行的jQuery代码。

**************************************************************************
其实就等于
var fn = function($){....};
fn(jQuery);

其实可以这么理解,不过要注意的是fn是不存在的
那个函数直接定义,然后就运行了。就“压缩”成下面的样子了
(function($){...})(jQuery)
**************************************************************************
简单理解是(function($){...})(jQuery)用来定义一些需要预先定义好的函数
$(function(){ })则是用来在DOM加载完成之后运行\执行那些预行定义好的函数.
**************************************************************************

六、开发jQuery插件时总结的一些经验分享一下。
1.先看
jQuery(function(){
});
全写为
jQuery(document).ready(function(){
});
意义为在DOM加载完毕后执行了ready()方法。

2.再看
(function(){
})(jQuery);
其实际上是执行()(para)匿名方法,只不过是传递了jQuery对象。

3.总结
jQuery(function(){ });用于存放操作DOM对象的代码,执行其中代码时DOM对象已存在。不可用于存放开发插件的代码,因 为jQuery对象没有得到传递,外部通过jQuery.method也调用不了其中的方法(函数)。
(function(){ })(jQuery);用于存放开发插件的代码,执行其中代码时DOM不一定存在,所以直接自动执行DOM操作的代码 请小心使用。

七、jquery $(document).ready() 与window.onload的区别
1.执行时间
window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行。
$(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕。

2.编写个数不同
window.onload不能同时编写多个,如果有多个window.onload方法,只会执行一个
$(document).ready()可以同时编写多个,并且都可以得到执行

3.简化写法
window.onload没有简化写法
$(document).ready(function(){})可以简写成$(function(){});

图片说明:

栗子:

$(window).load(function() {
$("#btn-upload").click(function(){ //比如说:
uploadPhotos();
});
});

八、用$(window).load(function(){...})而不用body.onload()的几个理由
1.同时加载多个函数,我们必须这样写
<body onload="fn1(),fn2()"></body>看起来极其丑陋.
如果用$(window).load()我们可以这样加载多个函数

$(window).load(function() {
    alert("hello,我是jQuery!");
});
$(window).load(function() {
    alert("hello,我也是jQuery");
});

2.用body.Onload()不能够做到js和html完全分离,这是一个很严重的问题.
另外用$(window).load(function(){...})和body.onload()都存在同样一个问题,因为开始也说到了,它们都需要等到页面的所有内容加载完毕才执行.

$(document).ready(function(){}),或简写为$(function(){}),$(window).load(function(){...})往往需要结合具体需要而作不同的选择。

注意:

IE只有在页面不是嵌入frame中的情况下才和Firefox等一样,先执行$(document).ready()的内容,再执行原来的onload方法。对于嵌入frame中的页面,也只是绑定在load事件上执行,所以自然是在原来的onload绑定的方法执行之后才轮到。而这个页面中正好在测试环境下有一个访问不到的资源,那十几秒的延迟正是它放大出的时间差。

深入理解,函数声明、函数表达式、匿名函数、立即执行函数、window.onload的区别.的更多相关文章

  1. JS执行顺序-函数声明提升、匿名函数、函数表达式

    大方向上: JS 是按照 代码块 进行 编译.执行 的. 学习至: 1.变量声明提升 2.新唐的博客 3.js中匿名函数的创建与调用方法分析 4.前端圣经 - <高程三> 5.深入理解变量 ...

  2. JavaScript学习总结(三、函数声明和表达式、this、闭包和引用、arguments对象、函数间传递参数)

    一.函数声明和表达式 函数声明: function test() {}; test();    //运行正常 function test() {}; 函数表达式: var test = functio ...

  3. JQuery语法 JQuery对象与原生对象互转 文档就绪函数与window.onload的区别

    [JQuery语法] 1.jQuery("选择器").action();通过选择器调用事件函数,但是jquery中,jquery可以用$(“选择器”).action();   ① ...

  4. JS函数声明与定义,作用域,函数声明与表达式的区别

    Scoping & Hoisting 例: var a = 1; function foo() { if (!a) { var a = 2; } alert(a); }; foo(); 上面这 ...

  5. 八、React实战:可交互待办事务表(表单使用、数据的本地缓存local srtorage、生命同期函数(页面加载就会执行函数名固定为componentDidMount()))

    一.项目功能概述 示例网址:http://www.todolist.cn/ 功能: 输入待做事项,回车,把任务添加到 [正在进行] [正在进行] 任务,勾选之后,变成已[经完成事项] [已完成事务], ...

  6. (译)详解javascript立即执行函数表达式(IIFE)

    写在前面 这是一篇译文,原文:Immediately-Invoked Function Expression (IIFE) 原文是一篇很经典的讲解IIFE的文章,很适合收藏.本文虽然是译文,但是直译的 ...

  7. 立即执行函数(IIFE)

    立即执行函数(IIFE) 看到这里,相信你一定迫不及待地想知道究竟如何做了吧,其实很简单,只需要用括号全部括起来即可,比如下面这样: (function(){ /* code */ }()); 为什么 ...

  8. JS中的匿名函数自执行、函数声明与函数表达式

    先看一段jQuery源码中匿名函数自执行的例子: (function( window, undefined ) { // jquery code })(window); 另外一种常见的写法: +fun ...

  9. javascript中函数声明和函数表达式浅析

    记得在面试腾讯实习生的时候,面试官问了我这样一道问题. //下述两种声明方式有什么不同 function foo(){}; var bar = function foo(){}; 当初只知道两种声明方 ...

随机推荐

  1. BlockingQueue使用

    import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import ja ...

  2. oracle从零开始学习笔记

    查询现有数据库:select name from V$database; 解锁用户scott:alter user scott account unlock; 普通用户连接:conn scott 默认 ...

  3. 【转载】C/C++中#ifdef和#endif的用法

    转于 http://www.cnblogs.com/renyuan/archive/2013/05/22/3092362.html 今天笔试的时候遇到这个问题,整理一下! 一般情况下,源程序中所有的行 ...

  4. 【转】Objective-C中的instancetype和id关键字

    原文:http://blog.csdn.net/wzzvictory/article/details/16994913 一.什么是instancetype instancetype是clang 3.5 ...

  5. KSImageNamed-Xcode

    KSImageNamed-Xcode   非常的给力的XCODE图片浏览插件; What is this? Can't remember whether that image you just add ...

  6. C# 消息队列 RabbitMQ

    1.引言 RabbitMQ——Rabbit Message Queue的简写,但不能仅仅理解其为消息队列,消息代理更合适. RabbitMQ 是一个由 Erlang 语言开发的AMQP(高级消息队列协 ...

  7. vertica系列:解锁table

    Vertica 表发生死锁后, 通过下面3个查询即可解锁. --步骤1: 找到被锁表的 transaction_idselect transaction_id, t.* from v_monitor. ...

  8. TypeScript学习笔记 (一)基础特性

    一. 字符串新特性 1. 多行字符串 var str = ``; 2. 字符串模板 var world = "world"; var str = `hello ${world}`; ...

  9. magrittr管道操作符使用解释(一)

    使用管道操作符提高代码简洁性 在编写R语言代码时,有时候需要对一个变量进行一系列的运算,例如对于一个同时包含数值列和字符串列的数据框,如果要计算所有数值列之间的相关系数,一般要分两步,第一步首先筛选数 ...

  10. JQ 实现监测input中值的变化并绑定到另个input

                    $('#input').bind('input propertychange', function () {                     $('#myDiv ...