从定义函数说起

如何定义函数?

一般来说,定义函数的方式有两种,分别是函数声明函数表达式

//函数声明
function foo1() {
console.log("hello");
}

//函数表达式
var foo2 = function () {
console.log("javascript");
}

第一次使用的时候并没有觉得这两者有什么特别的差别,那我们来试试在最前面加入执行函数的代码,是最前面哦。

foo1();
foo2();

定义函数 执行一下,WTF!怎么报错了,我们看看错误是什么? Uncaught TypeError: foo1 is not a function ,OK,我们来设置断点来分析一下,这里,我们把 foo1foo2 加入监视窗口;我们可以看到 foo1 函数执行之前就已经获得了定义,而 foo2 函数却显示未定义,到这里我们就明白了。但是为什么 foo1 就生效了呢?我们来说说声明提升。

声明提升

刚才我们在一开始调用 foo1 的时候发现该函数已经被定义了,证实了采用声明形式定义的函数有声明提升的特征,何为声明提升?即可以在定义该函数之前调用。而采用表达式形式定义的函数只能顺序执行,你不能在定义该函数之前调用(大家可以自己试试把调用函数的代码放在不同位置,以及调换两个函数的位置)。 接下来我们通过另一段代码,来看看函数声明和变量声明。 函数声明与变量声明

var foo;
function foo() {
console.log("hello javascript");
}
foo();

我们声明了一个变量 foo ,接着又定义了一个函数 foo ,我们通过监视窗口发现 foo 一直被定义成了一个函数,显然,函数声明的优先级高于变量声明。真的是这样吗?把上面的代码稍微改造一下。 函数声明与变量声明

var foo = "1";
function foo() {
console.log("hello javascript");
}
foo();

执行一下,咦?又报错了, Uncaught TypeError: foo is not a function ,在执行 var foo = "1" 之后,监视器写着 foo: "1" ,我们声明的函数被变量覆盖了,到这里我们可以得到结论了,经过初始化的变量声明优先级高于函数声明。

关于参数

在函数中引入参数,想必大家肯定很熟悉了。

var str = "hello world";

(function foo(obj) {
console.log("first inside:" + obj); // first inside:hello world
obj = "hello javascript";
console.log("second inside:" + obj); // second inside:hello javascript
}(str));

console.log("outside:" + str); // outside:hello world

我们都知道在函数内部的改变全局变量的值对外部是不可见的,就像上面的代码,我们在函数内部改变 str 的值,对外部毫无影响。现在我们把参数换成对象试试会怎样。

var people = {
age: 18,
sex: "man",
location: "hangzhou"
};

(function foo(obj) {
console.log("first inside:" + obj.age); // first inside:18
obj.age = 23;
console.log("second inside:" + obj.age); // second inside:23
}(people));

console.log("outside:" + people.age); // outside:23

涨知识了,如果参数是对象,在函数内部对该对象做出的改变对外部是可见的。

课后题?

function foo() {

}
foo();
var foo = function () {

}

foo()执行的是哪个函数呢?把三段代码的位置调换一下又会有是什么情况呢?大家可以自己研究一下。

写在最后

昨天开始打算写这篇文章之前,本以为很好理解的,然而自己就被第一个定义函数的方式卡了很久,之前听室友讲维护一个blog就够累的了,还录制教学视频、维护个人网站?当时还不觉得,结果轮到自己上手写文章的时候才发现真的很不容易,真的很佩服一直坚持写blog,分享文章的那些人,正是你们乐于分享,才让更多的开发者能够了解到更广泛的知识。另外,作者作为前端新兵,本文肯定有不当之处,欢迎批评~~~