一、函数
1.1 定义函数
1 function 关键字方式 2 function 函数名(参数1,参数2){ 3 code... 4 }; 5 6 表达式方式 7 var 函数名 = function(参数1,参数2){ 8 code... 9 };
1.2 函数特点
函数名就是变量名
函数调用 必须加()
关键字方式定义的函数,会存在函数提升(在函数定义的前面,调用函数)
1.3 函数的参数问题
形参和实参
实参数量>形参数量 多给的实参会被忽略
实参数量<形参数量 多出的形参,默认值undefined
参数默认值
ES6 新增的语法
有默认值的参数 一定在后面
1 function demo(a,b=默认值){ 2 3 }
可变数量的参数
arguments对象 可以获取所有的实参
只能在函数中使用
arguments是类数组对象,用法同数组,可以使用for循环遍历
1.4 return
return 可以结束函数
return 返回值
Js return 只能返回一个值
1.5 回调函数
一个函数就可以接收另一个函数作为参数,这种函数就称之为回调函数(高阶函数)
1 function add(x, y, f) { 2 return f(x) + f(y); 3 } 4 add(-5, 6, Math.abs)
1.6 自调函数
如果多个自调函数连续写,中间必须加:否则报错
产生局部作用域
有效避免全局变量污染
1 (function(){ 2 3 })(); 4 (function 函数名(){ 5 6 })()
1.7 递归函数
用递归 实现阶乘
1 function multiply(n){ 2 if (n == 1){ 3 return 1 4 } 5 return n * multiply(n-1) 6 }
闭包函数
通常需要 函数中 返回一个 函数
目的 把一个局部作用域的 数据 让外层的作用域使用
1 function count() { 2 var arr = []; 3 for (var i=1; i<=3; i++) { 4 arr.push((function (n) { 5 return function () { 6 return n * n; 7 } 8 })(i)); 9 } 10 return arr; 11 } 12 13 var results = count(); 14 var f1 = results[0]; 15 var f2 = results[1]; 16 var f3 = results[2]; 17 18 f1(); // 1 19 f2(); // 4 20 f3(); // 9
二、JavaScript 作用域
2.1 局部作用域
函数中使用定义的变量就是局部变量,只能在本函数中使用
2.2 全局作用域
在函数外面定义的变量是全局变量,哪都可以使用
变量,使用var是声明 没有var是使用变量,如果是在函数内使用var来声明变量,在函数内覆盖同名的全局变量
变量提升 在变量声明之前 去使用变量,会得到 undefined,而不是报错
函数内,如果声明了跟全局变量名同名的局部变量,在声明之前使用该变量,得到undefined(该变量已经是局部变量啦)
1 var a = 100 2 function demo(){ 3 console.log(a) 4 var a = 200 5 }
2.3 作用域链
当一个作用域 使用某个变量时,先从本作用域中找,如果没有就去父作用域,再没有 父作用域的父作用域,一直到 全局作用域
构成了一个作用域链
1 function demo(){ 2 function fn(){ 3 function fn1() { 4 5 } 6 } 7 }
2.4 块状作用域(ES6)
let关键字也可以声明变量,同var一样
但是let关键字声明的变量,会在结构语句中产生 块状作用域
ES6建议 使用let代替var
for (let i = 0; i < 10; i ++) { } console.log(i) 变量不存在 Uncaught ReferenceError: i is not defined
三、JavaScript对象
3.1 Object类型
1 创建 直接量 2 var obj = {name:'xiaolili', age:100, getInfo:function( 3 console.log(this.age) 4 )} 5 6 new 构造函数 7 var obj = new Object() 8 obj.name = 'xiaolili' 9 obj.age = 100
属性操作
1 读取或修改属性 2 console.log(obj.name) 3 obj.name = 'lili' 4 5 console.log(obj['name']) 6 obj['name'] = 'honghong' 7 8 删除属性 9 delete obj['name'] 10 delete obj.name 11 12 检测属性是否存在 13 'name' in obj
3.2 声明类(构造函数)
每个对象都有一个属性 .constructor 从而获取其构造函数
使用运算符 instanceof 可以判断一个对象是否存在某个构造函数
1 function User(name, age){ 2 this.name = name 3 this.age = age 4 5 this.getInfo = function(){ 6 console.log(this.name, this.age) 7 } 8 } 9 10 var u = new User('lxx', 45)
3.3 this
this表示方法 所属的对象
全局函数中的this 指向window
3.4 原型和原型链
什么是原型
每一个JavaScript对象都和另一个对象关联,并从另一个对象继承属性,另一个对象就是"原型"
用直接量创建的对象 都具有同一个原型对象 Object.prototype
原型链
对象的原型也有原型,构成了原型链
使用对象中某个属性的时候,先从对象中找 如果没有 从原型上找,原型如果也没有 继续向上找,直到顶层
获取原型
构造函数 .prototype
对象 .__proto__
给原型添加属性或方法
任意的对象 都可以在对象实例化完成后,添加属性和方法
检测属性 是自由属性还是继承自原型的属性
obj.hasOwnProperty(proName)
创建对象时指定原型
Object.create(原型对象)