## JS函数
- 函数也是一个对象. 具有Object的所有功能
- 不同的是, 函数对象中可以保存一些可执行的代码.并且在需要的时候可以调用这些代码
#### 函数声明式创建
function 函数名 (形参){
语句
}
函数调用: 函数名(实参)
- 如果需要函数中的代码执行. 则要对函数进行调用
- 函数执行几次就调用几次.
#### 函数表达式创建
var 变量 = function (形参){
语句
}
函数调用: var 变量1 = 变量()
- 变量1当作接口接收函数
#### Function 构造函数
var fn = new Function
#### 回调函数: 作为一个函数的参数形式存在的函数
#### 匿名回调函数: 没有变量定义的函数作为参数形式存在
(function(){})
函数调用: (); 直接使用括号来调用匿名函数
#### 自调函数: 只定义会自动调用
- () ();
- 第一个小括号. 定义函数
- 第二个小括号. 调用函数(可以传递实参)
- 作用: 可以将所有全局内容改为局部内容
- ````(function({})) ();````
#### 内部函数
function fn(){
function n( ){ }
}
n();
#### 函数的形参和实参
- 定义函数时,可以在()中指定数量不等的形参
- 多个形参之间用逗号隔开
- 在函数中定义形参,就相当于在函数中声明了变量但并没有赋值
- 在调用时可以指定实参
- 实参会赋值给对应的形参
#### 形参和实参的注意事项
- JS函数在调用时,浏览器不会检查形参的类型和个数
- 实参可以是任意数据类型(可以是对象也可以是函数)
- 实参也可以是任意数量
- 如果多于形参,则不会使用
- 如果少于形参,则没有对应实参的形参将会是undefined
#### 函数的返回值
- 返回值简单说就是函数的执行结果
- 通过return来设置函数的返回值
- 调用函数时可以用任意变量来接收函数的返回值
- 如果没有return返回函数的值,则函数没有意义
- return 返回值可以是任意的数据类型
- return也可直接跳出函数. 后面的所有代码都不会执行
#### 方法和调用
- 当一个对象的属性是一个函数时. 称这个函数是这个对象的方法
- 函数和方法只是称呼上的不同. 本质没有区别
- 调用对象中的函数时,称之为调用对象的方法
----------
### 作用域
- 作用域简单来说就是指一个变量的作用范围
- 作用域分为两类:
- 全局作用域
- 函数作用域
##### 全局作用域
1. 所有直接在script标签中编写的代码都在全局作用域中
2. 全局作用域在打开网页时创建.网页关闭时销毁
3. 全局作用域中有一个全局对象: window
- 在全局作用域中创建的变量都会作为window对象的属性保存
- 在全局作用域中创建的函数都会作为window对象的方法保存
4. **在全局作用域中创建的变量都是全局变量.可以在任意位置访问**
##### 函数作用域
- 函数作用域可以理解为全局中的小的作用域
- 函数作用域在函数调用时创建,在调用结束时销毁
- 每调用一次函数就会创建一个新的函数作用域
- 在函数作用域中可以访问到全局变量
- **但在全局作用域中无法访问到函数作用域中的变量**
- 函数中创建的变量如果不写 var 则会变成全局变量
##### 查找变量的机制
- 在函数中使用一个变量时,它会先在自身的作用域中寻找
- 如果有就直接使用,如果没有则去上一级作用域中寻找
- 找到则使用,如果没找到,则继续寻找,直到找到全局作用域为止
- 如果全局作用域中依然没有,**则会报错**
----------
### 声明提前
##### 变量声明提前
- 使用var关键字声明的变量,会在所有的代码执行前被声明,但不会被赋值
- 值为undefined
- 如果声明一个变量不使用var关键字,则不会有声明提前的特性.它会等到代码执行时才创建
##### 函数声明提前
- 使用函数声明式创建的函数,会在所有的代码执行之前被创建
- 可以在函数声明之前就能对该函数进行调用
----------
### this
1. 以构造函数形式调用.this就代表即将new出来的对象
2. 以函数的形式调用或在全局环境下 this就是window fn()
3. 函数作为对象的属性并被调用时. this是调用方法的对象 obj.fn()
4. 使用call和apply调用时,this是第一个参数
5. 回调函数中的this:不是我们指定的
- dom事件回调函数中的this -- dom元素
- 定时器回调函数 -- window
- arr.forEach(function(index,item){}) -- window
----------
#### 工厂函数
- 返回值是一个对象
- 解决了字面量创建多个对象有重复代码的问题
function createPerson (name,age){
var obj = new Object();
obj.name=name;
obj.age=age
obj.sayName=function( ){
console.log("大家好,我是:"+this.name+"年龄:"+this.age+"性别:"+this.gender);
};
return obj;
}
var person=createPerson("孙悟空",18,"男");
#### 构造函数
- 构造函数专门用来创建对象的函数
- 构造函数需要通过 new 关键字来创建
- 构造函数首字母一般都是大写
###### 构造函数执行流程
1. 创建新的对象
2. 将新创建的对象设置为函数中的this
3. 逐行执行函数
4. 将新创建的对象作为返回值返回
**如果以构造函数的形式调用. this就是构造函数创建出来的对象**
- 使用同一个构造函数创建的对象称之为一类对象
- 通过构造函数创造的对象称之为该函数的实例对象
###### instanceof
- 可以检查一个对象是否是一个构造函数的实例对象
- 语法: 对象 instanceof 构造函数
- 所有的对象都是Object实例对象的后代
#### 原型 prototype
- 每创建一个函数,浏览器都会为函数添加一个原型属性
- 这个属性对应是一个对象 称之为原型对象
- 当以构造函数的形式调用函数时, 它所创建的对象中都会有一个隐式原型属性__proto__
- 可以通过隐式原型属性来访问对象
- 添加属性可以在prototype上添加使其构成原型链
#### 原型的注意事项
- 原型就相当于一个公共区域.我们可以把对象中共有的属性共有的方法统一保存到该区域里
- 这样不用添加多个重复的属性或方法,也不会污染全局作用域
- 当我们去调用一个对象的属性或方法时,它会先去对象自身中寻找
- 如果找到则直接使用,如果没找到,则去原型对象中寻找.
- 如果原型中有则返回原型中的值
- 如果原型中没有,则去原型的原型中寻找.找到了则直接使用,以此类推
- 会一直找到Object的原型中
- Object.prototype.__proto__ 为null
- 如果它里面依然没有,则**返回undefined**
###### hasOwnProperty()
- 检查一个属性是否属于对象自身