html定义js函数,声明JavaScript函数的六种⽅法
⼀个函数⼀次性定义的代码块可以多次调⽤。在JavaScript中,⼀个函数有很多元素组成,同时也受很多元素影响:js arguments
函数体的代码
函数的参数列表
接受外部变量域的变量
返回值
当函数被调⽤时,this指上下⽂
命名和匿名函数
函数对象作为变量声明
arguments对象(在ES6中的箭头函数中将丢弃这个)
这些元素都会影响到函数,但具体影响函数的⾏为还是取决于函数的声明类型。在JavaScript中常见的声明类型有以下⼏种⽅法:
函数声明类型对函数代码的影响只是轻微的。重要的是函数如何与外部组件交互功能(⽐如外部作⽤域、闭包、对象⾃⾝拥有的⽅法等)和调⽤⽅式(普通函数调⽤、⽅法调⽤和构造函数调⽤等)。
例如,你需要通过this在⼀个函数调⽤封闭的下下⽂(即this从外部函数继承过来)。最好的选择是使⽤箭头函数,很清楚的提供了必要的下下⽂。
⽐如下⾯⽰例:
class Names {
constructor (names) {
this.names = names;
}
contains(names) {
return names.every((name) => this.names.indexOf(name) !== -1);
}
}
var countries = new Names(['UK', 'Italy', 'Germany', 'France']);
箭头函数传给.every()的this(⼀个替代Names类)其实就是⼀个contains()⽅法。使⽤⼀个箭头(=>)来声明⼀个函数是最适当的声明⽅式,特别是在这个案例中,上下⽂需要继承来⾃外部的⽅法.contains()。
如果试图使⽤⼀个函数表达式来调⽤.every(),这将需要更多的⼿⼯去配置上下⽂。有两种⽅式,第⼀种就是给.every(function(){...}, this)第⼆个参数,来表⽰上下⽂。或者在function(){...}.bind(this)使⽤.bind()作为回调函数。这是额外的代码,⽽箭头函数提供的上下⽂透明度更容易让⼈理解。
这篇⽂章介绍了如何在JavaScript中声明⼀个函数的六种⽅法。每⼀种类型都将会通过简短代码来阐述。感偿趣?
函数声明(Function declaration)
函数声明通过关键词function来声明,关键词后⾯紧跟的是函数的名称,名称后⾯有⼀个⼩括号(()),括号⾥⾯放置了函数的参数
(para1,...,paramN)和⼀对⼤括号{...},函数的代码块就放在这个⼤括号内。
function name([param,[, param,[..., param]]]) {
[statements]
}
来看⼀个函数声明的⽰例:
// function declaration
function isEven (num) {
return num % 2 === 0;
}
isEven(24); // => true
isEven(11); // => false
function isEven(num) {...}是⼀个函数声明,定义了⼀个isEven函数。⽤来判断⼀个数是不是偶数。
函数声明创建了⼀个变量,在当前作⽤域,这个变量就是函数的名称,⽽且是⼀个函数对象。这个函数变量存在变量⽣命提升,它会提到当前作⽤域的顶部,也就是说,在函数声明之前可以调⽤。
函数声明创建的函数已经被命名,也就是说函数对的name属性就是他声明的名称。在调试或者错误信息阅读的时候,其很有⽤。
下⾯的⽰例,演⽰了这些属性:
// Hoisted variable
console.log(hello('Aliens')); // => 'Hello Aliens!'
// Named function
console.log(hello.name); // => 'hello'
// Variable holds the function object
console.log(typeof hello); // => 'function'
function hello(name) {
return `Hello ${name}!`;
}
函数声明function hello(name) {...}创建了⼀个hello变量,并且提升到当前作⽤域最顶部。hello变量是⼀个函数对象,以及hello.name包括了函数的名称hello。
⼀个普通函数
函数声明匹配的情况应该是创建⼀个普通函数。普通的意思意味着你声明的函数只是⼀次声明,但在后⾯可以多次调⽤它。它下的⽰例就是最基本的使⽤场景:
function sum (a, b) {
return a + b;
}
sum(5, 6); // => 11
([3, 7]).reduce(sum); // => 10
因为函数声明在当前作⽤域内创建了⼀个变量,其除了可以当作普通函数调⽤之外,还常⽤于递归或分离的事件侦听。函数表达式或箭头函数是⽆法创建绑定函数名称作为函数变量。
下⾯的⽰例演⽰了⼀递归的阶乘计算:
function factorial(n) {
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
factorial(4); // => 24
有关于阶乘(Factorial)相关的详细介绍,可以点击这⾥。
在factorial()函数做递归计算时调⽤了开始声明的函数,将函数当作⼀个变量:factorial(n - 1)。当然也可以使⽤⼀个函数表达式,将其赋值给⼀个普能的变量,⽐如:var factorial = function (n) {...}。但函数声明function factorial(n)看起来更紧凑(不需要var和=)。
函数声明的⼀个重要属性是它的提升机制。它允许在相同的作⽤域范围内之前使⽤声明的函数。提升机制在很多情况下是有⽤的。例如,当你⼀个脚本内先看到了被调⽤的函数,但⼜没有仔细阅读函数的功能。⽽函数的功能实现可以位于下⾯的⽂件,你甚⾄都不⽤滚动代码。
你可以在这⾥了解函数声明的提升机制。
与函数表达式区别
函数声明和函数表达式很容易混淆。他们看起来⾮常相似,但他们具有不同的属性。
⼀个容易记住的规则:函数声明总是以function关键词开始,如果不是,那它就是⼀个函数表达式。
下⾯就是⼀个函数声明的⽰例,声明是以function关键词开始:
// Function declaration: starts with "function"
function isNil(value) {
return value == null;
}
函数表达式不是以function关键词开始(⽬前都⼀般出现在代码的中间地⽅):
// Function expression: starts with "var"
var isTruthy = function(value) {
return !!value;
};
// Function expression: an argument for .filter()
var numbers = ([1, false, 5]).filter(function(item) {
return typeof item === 'number';
});
// Function expression (IIFE): starts with "("
(function messageFunction(message) {
return message + ' World!';
})('Hello');
条件中的函数声明
当函数声明出现if、for或while这样的条件语句块{...}时,在⼀些JavaScript环境内可能会抛出⼀个引⽤错误。让我们来看看在严格模式下,函数声明出现在⼀个条件语句块中,看看会发⽣什么。
(function() {
'use strict';
if (true) {
function ok() {
return 'true ok';
}
} else {
function ok() {
return 'false ok';
}
}
console.log(typeof ok === 'undefined'); // => true
console.log(ok()); // Throws "ReferenceError: ok is not defined"
})();
当调⽤ok()函数时,JavaScript抛出⼀个异常错误"ReferenceError: ok is not defined",因为函数声明出现在⼀个条件语句块内。注意,这种情况适⽤于⾮严格模式环境下,这让⼈更感到困惑。
⼀般来说,在这样的情况之下,当⼀个函数应该创建在基于某些条件内时,应该使⽤⼀个函数表达式,⽽不应该使⽤函数声明。⽐如下⾯这个⽰例:
(function() {
'use strict';
var ok;
if (true) {
ok = function() {
return 'true ok';
};
} else {
ok = function() {
return 'false ok';
};
}
console.log(typeof ok === 'function'); // => true
console.log(ok()); // => 'true ok'
})();
因为函数是⼀个普通对象,根据不同的条件,将其分配给⼀个变量,是⼀个不错的选择。调⽤ok()函数也能正常⼯作,不会抛出任何错误。
函数表达式
函数表达式是由⼀个function关键词,紧随其后的是⼀个可选的函数名,⼀串参数(para1,...,paramN)放在⼩括号内和代码主体放在⼤括号内{...}。
⼀些函数表达式的使⽤⽅法:
var count = function(array) { // Function expression
return array.length;
}
var methods = {
numbers: [1, 5, 8],
sum: function() { // Function expression
return duce(function(acc, num) { // func. expression
return acc + num;
});
}
}
count([5, 7, 8]); // => 3
methods.sum(); // => 14
函数表达式创建了⼀个函数对象,可以⽤在不同的情况下:
当作⼀个对象赋值给⼀个变量count = function(...) {...}
在⼀个对象上创建⼀个⽅法sum: function() {...}
当作⼀个回调函数.reduce(function(...) {...})
函数表达式在JavaScript中经常使⽤。⼤多数的时候,开发⼈员处理这种类型的函数,喜欢使⽤箭头函数。
命名函数表达式
当函数没有⼀个名称(名称属性是⼀个空字符串)时这个函数是⼀个匿名函数。
var getType = function(variable) {
return typeof variable;
};
getType.name // => ''
getType就是⼀个匿名函数,其getType.name的值为''。
当表达式指定了⼀个名称时,这就是⼀个命名函数表达式。它和简单的函数表达式相⽐具有⼀些额外的属性。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论