一:函数的定义
函数也是一个对象,也具有普通对象的功能。其在函数当中可以封装一些代码,在需要的时候可以去调用函数来执行这些代码。
使用typeof检查一个函数时会返回function
二:函数操作
(1)创建函数
语法一:
function 函数名([形参1,形参2...形参N]){
语句...
}
语法二:
var 函数名 = function([形参1,形参2...形参N]){
语句...
};
(2)调用函数(调用函数时,代码会按编写的顺序执行)
语法:
函数对象([实参1,实参2...实参N]);
fun() sum() alert() Number() parseInt()
三:参数(形参、实参)
形式参数(形参): 定义函数时,可以在()中定义一个或多个形参,形参之间使用,隔开;定义形参就相当于在函数内声明了对应的变量但是并不赋值,形参会在调用时才赋值。
实际参数(实参): 调用函数时,可以在()传递实参,传递的实参会赋值给对应的形参,调用函数时JS解析器不会检查实参的类型和个数,可以传递任意数据类型的值。如果实参的数量大于形参,多余实参将不会赋值,如果实参的数量小于形参,则没有对应实参的形参将会赋值undefined。实参可以是任意的数据类型
四:函数的返回值
使用return 来设置函数的返回值。
语法:
return 值
该值就会成为函数的返回值,可以通过一个变量来接收返回值
******return后边的代码都不会执行,一旦执行到return语句时,函数将会立刻退出。
****** return后可以跟任意类型的值,可以是基本数据类型,也可以是一个对象。
******如果return后不跟值,或者是不写return则函数默认返回undefined。
break、continue和return
- break
- 退出循环
- continue
- 跳过当次循环
- return
- 退出函数
方法(method):
可以将一个函数设置为一个对象的属性,当一个对象的属性是一个函数时,我们称这个函数是该对象的方法。
对象.方法名();
函数名();
五:作用域(全局作用域、函数作用域)
(1)全局作用域
******直接在script标签中编写的代码都运行在全局作用域中。
******全局作用域在打开页面时创建,在页面关闭时销毁。
******全局作用域中有一个全局对象window,window对象由浏览器提供, 可以在页面中直接使用,它代表的是整个的浏览器的窗口。
******在全局作用域中创建的变量都会作为window对象的属性保存,在全局作用域中创建的函数都会作为window对象的方法保存。
******在全局作用域中创建的变量和函数可以在页面的任意位置访问。在函数作用域中也可以访问到全局作用域的变量。
******尽量不要在全局中创建变量 。
(2)函数作用域
******函数作用域是函数执行时创建的作用域,每次调用函数都会创建一个新的函数作用域。
******函数作用域在函数执行时创建,在函数执行结束时销毁。
******在函数作用域中创建的变量,不能在全局中访问。
******当在函数作用域中使用一个变量时,它会先在自身作用域中寻找, 如果找到了则直接使用,如果没有找到则到上一级作用域中寻找,如果找到了则使用,找不到则继续向上找,一直到window全局作用域。
(3)变量的声明提前
******在全局作用域中,使用var关键字声明的变量会在所有的代码执行之前被声明,但是不会赋值。所以我们可以在变量声明前使用变量。但是不使用var关键字声明的变量不会被声明提前。
******在函数作用域中,也具有该特性,使用var关键字声明的变量会在函数所有的代码执行前被声明, 如果没有使用var关键字声明变量,则变量会变成全局变量。
(4)函数的声明提前
******在全局作用域中,使用函数声明创建的函数(function fun(){}),会在所有的代码执行之前被创建,也就是我们可以在函数声明前去调用函数,但是使用函数表达式(var fun = function(){})创建的函数没有该特性。
******在函数作用域中,使用函数声明创建的函数,会在所有的函数中的代码执行之前就被创建好了。
六:this(上下文对象)
******每次调用函数的时候,解析器都会将一个上下文对象作为隐含的参数传递进函数。
******this的五种的情况:
(1)以函数的形式调用时,this就是window
(2)以方法的形式调用时,this是调用方法的对象
(3)以构造函数的形式调用时,this是新建的那个对象
(4)使用call和apply调用时,this是指定的那个对象
(5)在全局作用域中this代表window
七:call和apply
****** call()
******apply()
这两个方法都是函数对象的方法需要通过函数对象来调用
通过两个方法可以直接调用函数,并且可以通过第一个实参来指定函数中this
不同的是call是直接传递函数的实参而apply需要将实参封装到一个数组中传递
八:arguments
******arguments
arguments和this类似,都是函数中的隐含的参数
arguments是一个类数组元素,它用来封装函数执行过程中的实参。所以即使不定义形参,也可以通过arguments来使用实参
arguments中有一个属性callee表示当前执行的函数对象
九:构造函数
******构造函数是专门用来创建对象的函数
******一个构造函数我们也可以称为一个类
******通过一个构造函数创建的对象,我们称该对象时这个构造函数的实例
******通过同一个构造函数创建的对象,我们称为一类对象
******构造函数就是一个普通的函数,只是他的调用方式不同:
如果直接调用,它就是一个普通函数
如果使用new来调用,则它就是一个构造函数
eg: function Person(){
}
构造函数的执行流程:
1.创建一个新的对象
2.将新的对象作为函数的上下文对象(this)
3.执行函数中的代码
4.将新建的对象返回
instanceof 用来检查一个对象是否是一个类的实例
- 语法:对象 instanceof 构造函数
- 如果该对象时构造函数的实例,则返回true,否则返回false
- Object是所有对象的祖先,所以任何对象和Object做instanceof都会返回true
- 枚举对象中的属性
for...in
语法:
for(var 属性名 in 对象){
}
for...in语句的循环体会执行多次,对象中有几个属性就会执行几次,
每次讲一个属性名赋值给我们定义的变量,我们可以通过它来获取对象中的属性
十:原型对象(prototype)
******创建一个函数以后,解析器都会默认在函数中添加一个prototype
prototype属性指向的是一个对象,这个对象我们称为原型对象。
******当函数作为构造函数使用,它所创建的对象中都会有一个隐含的属性执行该原型对象。
这个隐含的属性可以通过对象.__proto__来访问。
******原型对象就相当于一个公共的区域,凡是通过同一个构造函数创建的对象他们通常都可以访问到相同的原型对象。
我们可以将对象中共有的属性和方法统一添加到原型对象中,
这样我们只需要添加一次,就可以使所有的对象都可以使用。
******当我们去访问对象的一个属性或调用对象的一个方法时,它会先自身中寻找
(1)如果在自身中找到了,则直接使用。
(2)如果没有找到,则去原型对象中寻找,如果找到了则使用,
(3)如果没有找到,则去原型的原型中寻找,依此类推。直到找到Object的原型为止,Object的原型的原型为null,
(4)如果依然没有找到则返回undefined
******hasOwnProperty()
这个方法可以用来检查对象自身中是否含有某个属性
语法:对象.hasOwnProperty("属性名")