闭包
概念
闭包函数:声明在一个函数中的函数,叫做闭包函数。
闭包:内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。
特点
让外部访问函数内部变量成为可能;
局部变量会常驻在内存中;
可以避免使用全局变量,防止全局变量污染;
会造成内存泄漏(有一块内存空间被长期占用,而不被释放)
构造函数Function
function Person((name,age,job){
this.name =name;
this.age=age;
this.job=job;
}
let person1 = new Person('Mike',19,"software engineer")
let person2 = new Person("John",23,"hareware engineer")
构造函数相比于普通函数的特点
- 函数体里面会有对this的操作
- 函数名为大驼峰风格
原型和原型链
四个规则:
1、引用类型,都具有对象特性,即可自由扩展属性。
2、引用类型,都有一个隐式原型 __proto__
属性,属性值是一个普通的对象。
3、引用类型,隐式原型 __proto__
的属性值指向它的构造函数的显式原型 prototype
属性值。
4、当你试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么它会去它的隐式原型 __proto__
(也就是它的构造函数的显式原型 prototype
)中寻找。
原型链就是一个过程,原型是原型链这个过程中的一个单位,贯穿整个原型链。
扩展运算符
扩展运算符(spread)是三个点(...
)。它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列。
// ES5
[1, 2].concat(more)
// ES6
[1, 2, ...more]
let arr1 = ['a', 'b'];
let arr2 = ['c'];
let arr3 = ['d', 'e'];
// ES5的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
解构赋值
基本用法
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
var a = 1
var b = 2
var c = 3
// ES6
let [a, b, c] = [1, 2, 3]
数组中
// 只取部分值
let [a] = [1, 2, 3]
let [a, , c] = [1, 2, 3]
// 取嵌套值
let [a, , c] = [1, 2, [3, 4]]
let [a, , [c]] = [1, 2, [3, 4]]
// 如果取不存在的值呢
let [a, b] = [1]
// 如果没有的话,咱们给他一个默认值吧
let [a, b=2] = [1]
对象中
除了数组,解构同样适用于对象
let { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
函数参数中
function add(arr){
return arr[0] + arr[1];
}
add([1, 2]); // 3
// 将它的参数列表改写
function add([a, b]){
return a + b;
}
add([1, 2]); // 3
// 同样可以设置默认值
function add([a = 2, b = 2]){
return a + b;
}
add([1, 2]); // 3
add() // 4
// 也可以这样表示默认值
function add([a, b] = [2, 2]){
return a + b;
}
如何写好JS
三个原则:
- 各司其职:html/css/javascript各司其职。避免不必要的由js直接操作样式,用class表示状态
- 组件封装:插件化,模板化,抽象化
- 过程抽象
补充
高阶函数:以函数为参数、返回值
声明式编程比命令式扩展性更好,语法更简洁