函数是由一连串的子程序(语句的集合)所组成的,可以被外部程序调用。向函数传递参数之后,函数可以返回一定的值。
通常情况下,JavaScript代码是自上而下执行的,不过函数体内部的代码则不是这样。如果只是对函数进行了声明,其中的代码并不会执行。只有在调用函数时才会执行函数体内部的代码
注意是:在JS中函数也是一个对象,在使用typeof判断一个函数类型时返回是:function
函数:1.函数定义 2.函数形参 3.函数返回值
方式一:
// 定义函数方式一:一般不使用这种方式
var fun = new Function(" console.log('加油,学习前端!');");
// 调用函数
fun();
// 判断函数类型
alert(typeof fun);//返回值是:function,注意是:函数也是对象
方式二:常用
语法:
function 函数名([形参1,形参2,..]){
语句...
}
function fun2() {
console.log("您好,明天!");
}
fun2();
方式三:常用
语法:
var fun = new function([形参1,形参2,..]){
语句...
};
// 定义函数方式三:声明函数的方式,一般要在`{}`后面加上`;`
/**
* 注意是:方式三是将声明函数赋值给fun3,这种方式
* 一般是需要在`{}`后面加上`;`
*/
var fun3 = function () {
console.log("您好,海康!");
};
fun3();
一般方式一了解,方式二和方式三是需要重点掌握的
1.可以在函数的
()中来指定一个或多个形参(形式参数),多个形参之间使用,隔开,声明形参就是相当于在函数内部声明了对应的变量但是并没有赋值例如: function f1(a,b){}; 上述的定义相当于下面的: function f1(){ var a; var b; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
2.调用函数时解析器不会检查实参的类型
所以要注意是:是否有可以接收到非法的参数,如果有可以则需要对参数进行类型的检查
3.函数的实参可以是任意的数据类型
4.调用函数时,解析器不会检查实参的数量
多余实参不会被赋值
如果实参的数量少于形参的数量,则没有对应的实参的形参将是
undefined
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>函数形参</title>
</head>
<body>
<script type="text/javascript">
// 函数形参
function f(a,b) {
alert(a+b);
}
f(1,2);
f(1,"3");//注意是:实参可以为任意的数据类型
f(1,2,3,5);//注意是:1赋值给a,2赋值给b,多余的参数会被忽略
f(1);//注意是:如果实参数量少于形参数量时,1赋值给a,b则为`undefined`
</script>
</body>
</html>
可以使用
return来设置函数的返回值语法:
return 值;
return后的值将会作为函数的执行结果返回,可以定义一个变量,来接收该结果在函数
return后的语句都不会执行如果
return语句后不跟任何就相当于返回一个undefined,如果函数中不写return,则也返回undefined
return后可以跟任意类型的值
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>函数返回值</title>
</head>
<body>
<script type="text/javascript">
function sun(a,b,c) {
// 注意是:如果不写return语句,返回是:undefined
// 如果只是:return; 返回是:undefined
return a+b+c;
}
var num = sun(1,2,3);
alert(num);
</script>
</body>
</html>
注意是:调用函数时,加上()和不加括号的区别,如下:
var fun = function f1(a,b){
return a+b;
};
alert(fun);//表示打印的是该函数对象,输出的内容是:
/**
* var fun = function f1(a,b){
* return a+b;
* };
*/
alert(fun(1,2));//表示执行f1函数返回的结果是:3
return break continue
return可以结束整个函数
break可以退出当前的循环
continue用于路过当次循环
立即执行函数本质就是匿名函数
语法:
(function([实参1,实参2,…]){
语句…
})([实参1,实参2,…]);
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>立即执行函数</title>
</head>
<body>
<script type="text/javascript">
/**
* 立即执行函数本质就是一个匿名函数
*/
(function (a,b) {
alert("a+b="+(a+b));
})(3,5);
</script>
</body>
</html>
语法:
for(var 变量 in 对象){
语句…
}
for ... in语句,对象中有几个属性,循环体就会执行几次每次执行时,会将对象中的一个属性的名字赋值给变量
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>枚举对象中的属性</title>
</head>
<body>
<script type="text/javascript">
var obj = {
name:"海康",
age:23,
sex:"男",
address:"湛江海康",
};
/**
* 枚举对象的语法:
* for(变量 in 对象名){
* 语句...
* }
*/
for (const objKey in obj) {
console.log("对象属性名:"+objKey);
console.log("对象属性值:"+obj[objKey]);
}
</script>
</body>
</html>
作用域:
作用域指定一个变量的作用的范围
在
JS中一共有两种作用域:
- 全局的作用域
- 直接编写在
script标签中的JS代码都是全局作用域- 全局作用域在页面打开时创建,在页面在关闭时销毁
- 在全局作用域中有一个全局的
window对象,它代表的是一个浏览器窗口对象,它由浏览器创建我们可以直接使用- 在使用作用域中:
- 创建的变量都会作为
window对象的属性性保存- 创建的函数都会作为
window对象的方法他保存- 全局作用域的变量都是全局变量
- 在页面的任意的部分都可以访问的到
- 函数作用域(也称为:局部作用域)
全局作用域:就是直接编写在script标签中的代码,随着页面的打开创建,关闭销毁
在全局作用中:
window对象的属性保存window对象的方法保存<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>08_全局作用域</title>
</head>
<body>
<script type="text/javascript">
// 定义变量
var a = 100;
var b = 200;
// 上述定义的两个变量都是保存在`window`对象的属性中
// 可以使用window.属性的方式调用
console.log(window.a);//由于window是一个窗口对象,默认就是使用它,所以我们一般会省略掉
console.log(window.b);
//定义函数
function fun1(a,b) {
console.log(a+b);
}
// 上述定义的函数是保存在window对象中的方法中
// 可以使用window.方法名的方式调用
window.fun1(3,5);//由于window是一个窗口对象,默认就是使用它,所以我们一般会省略掉
</script>
</body>
</html>
变量的声明提前:
使用
var关键字声明的变量,会在所有的代码执行之前被声明(但是不会被赋值) 但是如果声明变量时不使用
var关键字时,则变量不会被声明提前函数的声明提前:
使用函数声明形式创建的函数
function 函数() {} 它会在所有的代码执行之前就被创建,所以我们在函数声明前来调用函数,使用函数表达式创建的函数,不会被声明提前,所以不能声明前调用
变量的提前声明就是使用var关键字,而函数的提前声明语法是:function 函数名(参数列表){语句...}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>声明提前</title>
</head>
<body>
<script type="text/javascript">
// 变量的声明提前语法是:var 变量名 = 值;
// 返回值是:undefined,原因是:在下面的13行才进行赋值
console.log(a);//不会被报错,因为是`a`变量被提前声明了,相当于在上面声明了:var a;
// 如果不写`var a = 100`,而是写成:`a = 100;` 会直接报错
var a = 168;
/**
* 函数的声明提前语法是:
* function 函数名(参数列表) {语句...}
*
* 注意是:
* var 变量名 = function(参数列表) {语句...}
* 这种方式不是函数的提前声明,会报错的,这是变量的提前声明,
* 如果使用这种方式调用函数时,会报错,因为变量值是undefined 调用undefined会直接报错
*/
function fun() {
alert("你好,函数的提前声明");
}
fun();
</script>
</body>
</html>
局部作用域就是在函数中定义的变量,并且在函数中定义的变量如果不使用var关键字时,默认定义就是全局变量,默认是window.变量名
函数作用域(局部作用域)
- 调用函数时创建函数作用域,函数执行完毕后,函数作用域销毁
- 每调用一次函数就会创建一个新的函数作用域,他们之间是相互独立的
- 在函数作用域中可以访问全局作用域的变量
- 当在全局作用域中无法访问到函数作用域中的变量
- 在函数作用中如果有与全局作用域的变量名相同,需要访问全局作用域中的变量时,可以使用
window.变量名来访问全局变量
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>10_函数作用域</title>
</head>
<body>
<script type="text/javascript">
/**
* 函数作用域
* 在函数中使用`var`关键字定义的变量就是函数变量
* 该变量的作用域只限于函数体内,如果在函数不使用`var`关键字定义变量
* 时,默认定义就是全局变量
*/
function fun() {
var a = 100;
b = 100;// 如果在函数中不使用var定义的变量,默认就是全局变量,默认使用`window.变量名`
console.log(a);
}
</script>
</body>
</html>
注意是:在函数作用域中也有提前声明的特性
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>作用域的练习</title>
</head>
<body>
<script type="text/javascript">
var a = 123;
function fun() {
alert(a);
}
fun();
// 结果:123
=====================
var a = 123;
function fun() {
alert(a);
var a = 456;
}
fun();
alert(a);
// 结果 :undefined 123
=====================
var a = 123;
function fun() {
alert(a);
a = 456;
}
fun();
alert(a);
// 结果 : 123 456
====================
var a = 123;
function fun(a) {// 形参相当于在:函数体中声明一个var a;
alert(a);
a = 456;
}
fun();
alert(a);
// 结果:undefined 123
=====================
var a = 123;
function fun() {
alert(a);
a = 456;
}
fun(123);
alert(a);
// 结果:123 456
</script>
</body>
</html>
Debug<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>debug</title>
</head>
<body>
<script type="text/javascript">
alert(d);
var a = 10;
var b = "hello";
c = true;
function fun(){
alert("hello");
}
var d = 35;
</script>
</body>
</html>
this【非常重点】解析器在调用函数时每次都会向函数内部传递进一个隐含的参数,
这个隐含的参数就是
this,this指向的是一个对象 这个对象我们称为函数执行的上下文对象
根据函数的调用方式的不同,
this指向不同的对象 1.以函数的形式调用时,
this永远都是window 2.以方法的形式调用时,
this就是调用方法的那个对象
重点:this就是代表当前的对象,当以函数调用时,传入就是window,当以方法的方式时,传入就是当前的对象
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>this关键字</title>
</head>
<body>
<script type="text/javascript">
/**
* 解析器在调用函数每次都会向函数内部传递进一个隐含的参数,
* 是每个对象都隐含有的
* 在以函数的方式调用函数时,this传入的就是`window`
* 在以方法的方式调用函数时,this传入就是`当前的对象`
*/
var name = "全局name";
function fun() {
alert("this当前是谁");
alert(this.name);
}
// 调用方式一:以函数方式调用传入是`window`对象
fun();
// 调用方式二:
// 以方法的方式调用传入是当前的对象
var obj = {
name:"海康",
sayFun:fun
}
// 以方法的方式调用
obj.sayFun();
</script>
</body>
</html>
this的练习在一个函数中,根据对象的不同输出当前的对象属性name的值
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>this的练习</title>
</head>
<body>
<script type="text/javascript">
function fun() {
// this代表就是当前的对象,所以可以通过this来动态的输出name属性性
alert(this.name);
}
var obj1 = {
name:"海康",
showName:fun
};
var obj2 = {
name:"南宁",
showName:fun
};
var obj3 = {
name:"西安",
showName:fun
};
obj1.showName();
obj2.showName();
obj3.showName();
/**
* 输出结果是:
* 海康
* 南宁
* 西安
*/
</script>
</body>
</html>
使用工厂方法创建的对象,使用的构造函数都是Object类型的,所以创建的对象都是Object这个类型
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>工厂方法创建对象</title>
</head>
<body>
<script type="text/javascript">
function createObject(name,age,sex) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sex = sex;
obj.sayName = function () {
alert(this.name);//使用this关键字输入当前对象的name属性的值
}
return obj;// 注意是;使用工厂方法创建对象时,一定要将创建的对象返回
}
var object1 = createObject("海康",21,"男");
var object2 = createObject("南宁",22,"女");
var object3 = createObject("西安",21,"男");
object1.sayName();
</script>
</body>
</html>