最近我开始维护别人的JavaScript代码。我正在修复错误,添加功能,并尝试整理代码并使其更加一致。
之前的开发人员使用了两种声明函数的方式,我无法确定是否有什么原因。
这两种方式是:
var functionOne = function() {
// Some code
};
而且,
function functionTwo() {
// Some code
}
为什么要使用这两种不同的方法,各自有哪些优缺点?是否有一种方法可以做到另一种方法无法实现的事情?
最近我开始维护别人的JavaScript代码。我正在修复错误,添加功能,并尝试整理代码并使其更加一致。
之前的开发人员使用了两种声明函数的方式,我无法确定是否有什么原因。
这两种方式是:
var functionOne = function() {
// Some code
};
而且,
function functionTwo() {
// Some code
}
为什么要使用这两种不同的方法,各自有哪些优缺点?是否有一种方法可以做到另一种方法无法实现的事情?
new Function()
可以用于将函数体传递为字符串。因此,它可以用于创建动态函数。同时也可以在不执行脚本的情况下传递脚本。
var func = new Function("x", "y", "return x*y;");
function secondFunction(){
var result;
result = func(10,20);
console.log ( result );
}
secondFunction()
这被称为函数表达式:
var getRectArea = function(width, height) {
return width * height;
};
console.log("Area of Rectangle: " + getRectArea(3,4));
// This should return the following result in the console:
// Area of Rectangle: 12
这被称为函数声明:
var w = 5;
var h = 6;
function RectArea(width, height) { //declaring the function
return area = width * height;
} //note you do not need ; after }
RectArea(w,h); //calling or executing the function
console.log("Area of Rectangle: " + area);
// This should return the following result in the console:
// Area of Rectangle: 30
我更喜欢将函数定义为变量:
let first = function(x){
return x[0];
}
改为:
function first(){
....
}
因为我可以在定义函数时使用表达式和装饰器,例如:
let safe = function(f){
try {f()...}
}
let last = safe(function(x){return x[0]}).
使用ES6,代码更加简短:
let last = x => x[0]
...........
function last(x){
return x[0];
}
......
let last = safe(x => x[0]);
Javascript 拥有一流函数。这意味着它们可以像任何其他变量一样处理。函数可以作为参数传递到函数中,从函数返回,并且可以存储在变量中。
然而,将函数存储在变量中(函数表达式)并不是创建函数的唯一方法,还可以通过函数声明来完成。以下是两者的关键区别:
以下是一个示例:
try {
functionOne();
} catch (e) {
console.log('i cant run because im not hoisted');
}
functionTwo();
// function expression, does not get hoisted
let functionOne = function randomName() {
// Some code
};
// function declaration, gets hoisted
function functionTwo() {
console.log('I get hoisted');
}
try {
randomName(); // this isn't the proper name, it is functionOne
} catch (e) {
console.log('You cant call me with randomName my name is function one');
}
:
let functionOne
的声明被提升了。但它没有被初始化,甚至没有被赋值为 undefined
。因此,会出现错误:_Uncaught ReferenceError: Cannot access 'functionOne' before initialization_。 - Pavlo Maistrenko需要注意的一个重要点是:
假设有两个函数:
sum(1,2);
const sum = function(first, second) {
return first + second;
}
sum(1,2);
function sum(first, second) {
return first + second;
}
在这种情况下,由于存在变量提升,因此此函数不会出现任何错误。
JavaScript表达式: 返回一个值的内容
示例: 在Chrome控制台中尝试以下操作:
a = 10
output : 10
(1 + 3)
output = 4
声明/语句:不返回值的语句
示例:
if (1 > 2) {
// do something.
}
这里 (1>2) 是一个表达式,但 'if' 语句不是。它没有返回任何内容。
同样地,我们有函数声明/语句和函数表达式
让我们举个例子:
// test.js
var a = 10;
// function expression
var fun_expression = function() {
console.log("Running function Expression");
}
// funciton expression
function fun_declaration() {
console.log("Running function Statement");
}
重要提示:当JavaScript引擎运行上述js文件时会发生什么。
当此js运行时,以下事情将发生:
现在假设我们更新js如下。
// test.js
console.log(a) //output: udefined (No error)
console.log(fun_expression) // output: undefined (No error)
console.log(fun_expression()) // output: Error. As we trying to invoke undefined.
console.log(fun_declaration()) // output: running function statement (As fun_declaration is already hoisted in the memory).
var a = 10;
// function expression
var fun_expression = function() {
console.log('Running function expression')
}
// function declaration
function fun_declaration() {
console.log('running function declaration')
}
console.log(a) // output: 10
console.log(fun_expression()) //output: Running function expression
console.log(fun_declaration()) //output: running function declaration
上面评论中提到的输出结果,应该有助于理解函数表达式和函数语句/声明之间的区别。
function functionName() {}
,则随后无法在控制台中使用functionName()
(它会显示“未定义”),而在var functionName = function() {}
之后,则可以使用该函数。对于函数声明,您无法使用.bind()
方法,但是对于函数表达式可以使用。
函数声明:
function x() {
console.log(this)
}.bind('string')
x()
函数表达式:
var x = function() {
console.log(this)
}.bind('string')
x()
var functionOne = function() {}
定义在运行时,function functionTwo() {}
在解析时定义。
// Run-Time function declaration
functionOne(); // Calling functionOne function here will give an Error
var functionOne = function () {
// Some code
};
// Parse-Time function declaration
functionTwo(); // Calling functionTwo function will not give an Error
function functionTwo() {
// Some code...
}
运行时与解析时的解释 JavaScript 运行时 vs 解析时
try {
console.log("Success: ", add(1, 1));
} catch(e) {
console.log("ERROR: " + e);
}
var add=function(a, b){
return a + b;
}