两种js function 声明方式

2019-03-02 23:52|来源: 网路

http://helephant.com/2012/07/14/javascript-function-declaration-vs-expression/

 

 一种叫function declaration ,一种叫function operator.

 

function declaration 这样:

function destroyDeathStar() {
    alert("Stay on target, stay on target");
}

function operator 这样:

var destroyDeathStar = function() {
    alert("Stay on target, stay on target");
}
destroyDeathStar();

这两种最大的区别是declaration声明完了,会让代码parse,自动跑到最顶部,而operator不行,

所以这样的declaration是可以执行的,就是这个道理,也是这两种方式最大的区别

 

destroyDeathStar();
     
function destroyDeathStar() {
    alert("Stay on target, stay on target");
}

如果operator声明放在函数调用下面就会出错,找不到这个函数,所以说operator声明是在代码流里面的。所以,类似下面这种情况,operator就体现了它的优势:

 

var destroyDeathStar;
 
if(pilot == "Luke Skywalker") {
    destroyDeathStar = function() {
        alert("May the force be with you");
    }
}
else {
    destroyDeathStar = function() {
        alert("Gold Five to Red leader, lost Tiree, lost Dutch");
    }
}
destroyDeathStar(); // result will depend on the value of pilot when the code is run

 

operator就是 new 一个 function object ,这个function object要求是一个匿名函数。

 

因为function operator 是一个表达式,所以它比decalaration要灵活很多,比如放在一个对象里

var jabbaTheHut = {
 laugh : function() { alert("ho ho ho ho"); }
}
jabbaTheHut.laugh();

放在一个数组里:

var toDoToday = [
 function() { alert("Aren't you a little short for a storm trooper?") },
 function() { alert("Boring conversation anyway") },
];
for(var x=0; x<toDoToday.length; x++) {
 toDoToday[x]();
}

作为函数的参数:

// function statement
function itIsATrap(theTrap){
 theTrap();
}
 
// function operator
itIsATrap(function() { alert("Many Bothans died to bring us this information"); });

 

匿名函数很常见用于jquery里,很方便,比如:

$(document).ready(function() {
    alert("page has loaded.");
});

 

 

何时用什么

如果在if或loop里面,通常用operator,declaration无法实现因为他会被hoisted到最前面(除非没人用firefox访问你的脚本,因为在ff里这个会变成函数语句?)declarations在if或loop里面的兼容性不好。

如果你的函数只用一次,operator显然更简洁,对于单行jquery事件处理去修改一些css,operator很完美。

通过方法创建对象也一样,如果你担心效率,使用object prototype去声明一次,在对象被创建的时候。

如果在全局域,别人可以用到的,你需要考虑你创建的变量是否会和其他冲突,operator可以使用 例如namespacing这些手段可以让代码简洁。

对于用很多次的函数,两个方法因个人爱好而取。declaration更简便而且看起来像其他的语言(这算什么优势?)。

 

If you need to create a function inside an if statement or a loop, always use a function operator. The function declaration will not have the effect that you intended because it will be hoisted to the top of the code (unless you and all the people who will ever use your script are using Firefox because then it will become a function statement). Function declarations that are in if statements or loops will never consistently do what you expect cross browser.

If you are going to declare a function and use it only once and straight away, the function operator syntax is more concise than the function declaration. It is ideal for things like single line JQuery event handlers that toggle some CSS class.

Building up objects with methods is pretty much the same. Using the function operator to directly assign the method to the object means not having to go looking for the implementation. If you’re worried about performance, use the object prototype to declare the method only once for all the objects you create.

If you’re working in the global scope (writing javascript that is not inside a function), particularly if you are working on code that will be used by other people, you will want to avoid creating lots of variables that might conflict with other code. The function operator can be used with patterns such as namespacing to keep your code’s footprint as light as possible.

For any other functions that will be used a number of times, function declaration or function operator is a matter of personal preference. The function declaration is more concise and looks more like how you’d create a function in most other languages. If you’re using the function operator everywhere else and you want to make sure no one makes the mistake of putting a function declaration inside a conditional statement or a loop, then it might be worth considering mandating the function operator in your coding standards.

 


转自:http://www.cnblogs.com/fishenal/p/3364922

相关问答

更多
  • 当你使用var声明变量时,它们只在你的函数/构造函数的作用域中可见。 他们是私人的可以这么说。 在这种情况下,使用它与构造函数结合在一起。 当你实例化一个学生时,所有分配给它的值都是公开的。 首先,我建议将您的学生用大写字母S重命名为学生 。 这是一个约定,表明它是一个构造函数,您需要使用new关键字。 function Student(id, name, year){ this.id = id; this.name = name; this.year = year; } 如果你现在实例 ...
  • 最后我设法以这种方式,在服务器端 app= require('http').createServer(handler).listen(3000), io = require('socket.io').listen(3001); publisher = require('socket.io').listen(app); 在客户端 var socket = io.connect('http://localhost:3001'); var socket2 = io.connect('http://localh ...
  • 尝试这个 function doMyWork() { console.lot( 'TEST' ); } $('.number').on('click', doMyWork); $('select[name=receive]').on('change', doMyWork); 或者,如果您的元素是在DOM准备好后插入的: 如果DOM ready了目标元素,则不必使用此表单 function doMyWork() { console.lot( 'TEST' ); } $(document).o ...
  • 第一个是返回Function1[Int, Int]的无参数方法f1 。 scala> def f1: (Int => Int) = (x: Int) => x * x f1: (Int) => Int 第二个是一个参数方法f2 ,它接受一个Int并返回一个Int 。 scala> def f2(x: Int): Int = x * x f2: (x: Int)Int 您可以使用相同的语法调用f1和f2,但当您调用f1(2)它将扩展为f1.apply(2) 。 scala> f1 res0: (Int) ...
  • 使用标志来了解元素何时打开或关闭,并根据以下内容设置动画和缓动: $(document).ready(function() { $('#test').on('click', function() { var open = $(this).data('open'), easing = open ? 'easeOutBounce' : 'easeInBounce'; $('#preheader')[open ? 'slideUp ...
  • 是 C#支持单个语句可以分配多个局部变量 单个语句可以分配多个局部变量。 从C风格语法派生的语言通常允许您使用逗号在一个语句中声明多个变量。 C#语言允许这样做。 从8.5.1 Local variable declarations 声明多个变量的局部变量声明等效于具有相同类型的单个变量的多个声明。 此外,局部变量声明中的变量初始值设定项与声明后立即插入的赋值语句完全对应。 第一个IL代码; .locals init ([0] int32 aa, [1] int32 bb, ...
  • 主要区别在于Scala如何翻译这些定义。 在Scala中,一个lambda(一个匿名函数,一个函数值,一个函数文本)和一个方法是不同的东西。 你的第一个定义是Function1类的一个实例,它是用于lambdas的类之一,第二个仅仅是周围对象的一个方法,它编译为一个标准的Java方法。 两者之间的实际区别在于,Scala不能仅仅让您将方法称为值,这使得它成为二等公民。 处理高阶函数时会导致多余的间接。 例如,以下内容: 1.to(4).map(b) desugars到包装lambda: 1.to(4).m ...
  • 第一个例子不会被提升。 在您的第二个示例中,该函数将被提升。 在您的示例中,使用选项1(未提升): 如果您调用此代码: var myNewObject = new myObject(); myNewObject.whatAmI(); 在函数声明之前,您将收到错误。 但是在第二个示例中,函数被移动到封闭范围的顶部,声明并准备好使用(提升)。 http://www.sitepoint.com/back-to-basics-javascript-hoisting/ The first example wil ...
  • 在第一个示例中,您使用的是JavaScript函数作用域。 例如,它允许你做的是重新声明不同名称下的某些变量 - 例如,在你的代码中你将jQuery声明为$ - 这样你可以确定名为$ actual的变量是一个jQuery对象,而不是某些其他库声明的变量(如MooTools,Ext.js等)。 因此,显式函数范围的第一个优点是避免变量名称冲突。 但还有更多:在第一种情况下,您可以声明只能在“命名空间”功能的上下文中看到的“私有”变量。 例如,考虑这个例子: (function ($) { var jQ ...
  • 您的第一个脚本标记强制浏览器同步拉入该文件; 换句话说,浏览器将停止所有其他活动以下载,解析和执行脚本,然后再继续呈现页面。 在第二种情况下(你的google东西),动态创建一个脚本元素,并以异步方式加载文件。 第一个标签是阻塞 ,第二个标签不是。 有关async更多信息: https://developer.mozilla.org/en-US/docs/HTML/Element/Script 更多关于“阻止”脚本的影响: http://developer.yahoo.com/performance/rul ...