JS进阶 | 青训营

17 阅读3分钟

闭包

概念

闭包函数:声明在一个函数中的函数,叫做闭包函数。

闭包:内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。

特点

让外部访问函数内部变量成为可能;

局部变量会常驻在内存中;

可以避免使用全局变量,防止全局变量污染;

会造成内存泄漏(有一块内存空间被长期占用,而不被释放)

构造函数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表示状态
  • 组件封装:插件化,模板化,抽象化
  • 过程抽象

补充

高阶函数:以函数为参数、返回值

声明式编程比命令式扩展性更好,语法更简洁