两种定义函数方式的差异

这篇文档是我在面试前端工程师经常问的一个问题。

function print(content) {
  console.log(content);
}

var print = function (content) {
  console.log(content);
}

以上两种定义方式分别叫什么?差异是什么?

依据我面试结果的初步统计,大约70%的面试者答不出来,结果很让我意外。说明什么?说明绝大多数的所谓前端工程师基础太差了。

从术语上这两种定义方式有区别。

  • 函数语法定义方式
// 这是函数语法定义方式
function print(content) {
  console.log(content);
}
  • 函数表达式定义方式
// 这是表达式定义方式
var print = function (content) {
  console.log(content);
}

别小看这两种定义方式,它们的差异会把你给搞蒙。

函数语法定义方式

用函数语法定义一个函数,能获得定义提前的优待。

比如

// 这是函数语法定义方式
function print(content) {
  console.log(content);
}

print('Hello, JS');

备注:先定义后使用,呃。。很符合规矩。

print('Hello, JS');

// 这是函数语法定义方式
function print(content) {
  console.log(content);
}

备注:看上去好像先使用了才定义,呃。。怎么可以?

其实上面两种形式是等价的,原因就是代码在执行之前,编译器会把通过函数语法定义的函数提前定义。从而保证可以在任意处调用函数。

表达式定义方式

表达式定义方式和普通定义变量是一个道理(一样理解)

定义一个变量这样做

var name = 'xiaoming';

字符串xiaoming是一个字符串表达式

再比如

var name = 'xu' + 'xiaoming'

'xu' + 'xiaoming'是一个表达式,这个表示计算出结果xuxiaoming后,把结果赋值给了变量name。

以上很好理解吧。

那函数表达式呢

var print = function (content) {
  console.log(content);
}

你现在完全可以类推,function(content) { console.log(content )} 就是一个表达式。把这个表达式复制给了变量print。那么我们就可以称变量print是一个函数变量了。

有了这个函数变量print,我们就可以通过print变量执行该函数了。

var print = function (content) {
  console.log(content);
}

print('Hello,JS');

既然print是一个函数变量,一个变量没有定义之前肯定是不能使用的啦。

print('Hello,JS'); // 喔喔。。没定义怎么能使用?

var print = function (content) {
  console.log(content);
}

上面的代码肯定出错。

有人就问,函数语法定义法能提前,为啥函数表达式定义法就不提前呢?

那我提个问题,如果函数表达式定义法能提前,那定义变量是不是意味着都提前了呢。那就乱套了。

深入表达式定义法

直接使用表达式

函数语法定义法有提前优待,那也不能说表达式定义法就没有价值。价值可大了。

// 这是函数语法定义方式
function print() {
  console.log('Hello, JS');
}

setTimeout(print, 5000);
// 这是函数表达式定义方式
var print = function () {
  console.log('Hello, JS');
}

setTimeout(print, 5000);

乍一看,上面没啥区别啊。都是定义了一个函数,然后调用setTimeout,5秒钟后回调print。

来一个改进的写法,再看看

setTimeout(function() {
  console.log('Hello, JS');
}, 5000);

其实setTimeout只要一个函数变量,给一个就好。那既然在函数表达式定义方式中,是把一个函数表达式赋值给一个函数变量,那为什么不能直接把函数表达式给setTimeout呢?完全可以。

这样就避免多命名一个函数变量了,又节省时间,代码又紧凑好理解。

你们说,下面代码是不是一样一样的。

  • 变量的做法
var name = 'xiaoming';
console.log(name);

可以省一个变量

console.log('xiaoming');
  • 函数的做法
var print = function() {
  console.log('Hello, JS');
}

setTimeout(print, 5000);

可以省一个变量

setTimeout(function() {
  console.log('Hello, JS');
}, 5000);

在函数中定义函数

function printWelcome(name) {
  var addWelcome = function() {
    return '你好!' + name;
  }

  console.log(addWelcome());
}

printWelcome('xiaoming');

我就问你,函数里套函数酷不酷~晕不晕哈哈

{{ item.author.loginname }} {{ item.updateAtAge }}
登录后才能评论
登录