循环
While 循环
var start = 0; // 何时开始
while (start < 10) { // 何时停止
console.log(start);
start = start + 2; // 如何进入下一个项目
}
For 循环
for 循环明确要求定义起始点、结束点和循环的每一个步骤
。实际上,如果缺少这三个部分的任一部分,系统都会提示(Uncaught SyntaxError: Unexpected token
)。
for ( start; stop; step ) {
// 做这件事
}
// 注意区分 for 循环不同语句的分号
for (var i = 0; i < 6; i = i + 1) {
console.log("Printing out i = " + i);
}
递增与递减
x++ or ++x // 等同于 x = x + 1
x-- or --x // 等同于 x = x - 1
x += 3 // 等同于 x = x + 3
x -= 6 // 等同于 x = x - 6
x *= 2 // 等同于 x = x * 2
x /= 5 // 等同于 x = x / 5
x = 5;
5
x++;
5
x
6
++x;
7
x
7
x *=4;
28
x
28
x /= 4;
7
x
7
函数
// 声明 sayHello 函数
function add(x, y) {
// 函数主体!
}
函数会封装代码,使你能够轻松地使用(重复使用)一段代码。 Parameter
属于变量
,用于存储传递到函数中的数据
,并供函数使用。 Argument
是当函数被调用时传递到函数中的实际数据
。
function findAverage(x, y) {
var answer = (x + y) / 2;
return answer;
}
var avg = findAverage(5, 9);
上面函数中,x
和 y
是 parameter
,值 5 和 9 是 argument
。
如果你没有明确定义返回值,函数默认地将返回 undefined
。
function isThisWorking(input) {
console.log("Printing: isThisWorking was called and " + input + " was passed in as an argument.");
}
/**
* 输出: "Printing: isThisWorking was called and 3 was passed in as an argument"
返回: undefined
*/
function sleep() {
console.log("I'm sleepy!");
return "zzz";
return "snore";
}
sleep();
// "zzz"
// 函数将不会返回 "snore",因为第一个返回语句将退出函数。但是,一个函数中也可以出现多个返回语句。
作用域(Scope)
JS 中的两种不同的作用域:global scope
-全局作用域 和 function scope
-函数作用域。还有第三种作用域类型,即新版本的 JavaScript 中的块作用域
。
作用域可能导致的陷阱之一是作用域覆盖(overriding
)或遮蔽(shadowing
)。
尽量避免使用全局变量
,全局变量会跟其他名称相同的全局变量产生冲突。程序变得越来越大后,就很难跟踪这些变量并防止出现这一情况。
sayHi("Julia");
function sayHi(name) {
console.log(greeting + " " + name);
var greeting = "Hello";
/**
* var greeting;
console.log(greeting + " " + name);
greeting = "Hello";
*/
}
- JavaScript 会将
函数声明和变量声明提升到当前作用域的顶部
。 变量赋值不会提升
。- 在
脚本的顶部声明函数和变量
,这样语法和行为就会相互保持一致。
函数表达式
还记得可以向变量中存储任何内容吗?在 JavaScript 中,你也可以向变量中存储函数,存储在变量中的函数叫做函数表达式
。函数可以有名称,也可以是匿名的。使用变量名称调用在函数表达式中定义的函数。
var catSays = function(max) {
// 代码在此
};
catSays();
注意 function
关键字没有名称了,是一个匿名函数
,即没有名称的函数,你将其存储在了叫做 catSays 的变量中。变量 catSays 的值就是该函数包括的所有内容。
何时使用函数表达式及何时使用函数声明
取决于几项内容,你将在下个部分看到几种使用方法。但是,需要注意的一点是提升
。
函数表达式和提升(hoisting)
所有函数声明提升和加载后,脚本才会实际地运行
。函数表达式不会提升
,因为它们涉及变量赋值,只有变量声明会提升
。当解析器在脚本中到达该表达式之前,函数表达式不会加载
。如果在这之前调用函数,会出现错误:
`Uncaught TypeError: ... is not a function ...`
提升对声明的函数与函数表达式的影响之间的区别。注意,函数表达式没有提升
,但是声明的函数提升
了。
作为参数的函数
可以将函数存储在变量中使我们能够轻松地将函数传递到另一个函数中。传递到另一个函数中的函数叫做回调
。
// 函数表达式 catSays
var catSays = function(max) {
var catMessage = "";
for (var i = 0; i < max; i++) {
catMessage += "meow ";
}
return catMessage;
};
// 函数声明 helloCat 接受一个回调
function helloCat(callbackFunc) {
return "Hello " + callbackFunc(3);
}
// catSays 作为回调函数传入
helloCat(catSays);
内嵌函数表达式
函数表达式是指将函数赋为变量值。在 JavaScript 中,当你将函数作为参数内嵌传递给其他函数
时,也会发生这种情况。
// 将函数 displayFavorite 分配给变量 favoriteMovie 的函数表达式
var favoriteMovie = function displayFavorite(movieName) {
console.log("My favorite movie is " + movieName);
};
// 函数声明有两个参数:一个显示消息函数和一个电影名称
function movies(messageFunction, name) {
messageFunction(name);
}
// 调用 movies 函数,传入 favoriteMovie 函数和电影名称
movies(favoriteMovie, "Finding Nemo");
// 函数声明需要两个参数:一个显示消息的函数,以及一个电影名称
function movies(messageFunction, name) {
messageFunction(name);
}
// 调用 movies 函数,传入一个函数和电影名称
movies(function displayFavorite(movieName) {
console.log("My favorite movie is " + movieName);
}, "Finding Nemo");
这种函数表达式,即将函数内嵌传递给其他函数的语法在 JavaScript 中很常见。
为何使用匿名内嵌函数表达式?
匿名内嵌函数表达式通常与可能不会在其他地方重复使用的函数回调一起使用。是的,你可以将该函数存储在变量中,设个名称,然后像上面看到的示例一样传入该函数。但是,当你知道不会重复使用该函数
时,直接内嵌定义的话,会省去不少代码
。
function emotions(myString, myFunc) {
console.log("I am " + myString + ", " + myFunc(2));
}
emotions("happy", function out(num) {
var str = "";
for (var i = 0; i < num; i++) {
str +="ha";
}
str += "!";
return str;
});
// 输出:I am happy, haha!