JavaScript/ES6

1. Symbol类型

它的功能类似于一种标识唯一性的ID, 每个Symbol实例都是唯一的:

let s = Symbol('描述语句')
s + '' // 报错,symbol不能强类型转换

共享,判断是否存在这个symbol,存在就返回,不存在就创建:

Symbol.for(key值)
Symbol.keyFor(uid)  //共享的可以输出key值

 

应用场景:

使用Symbol来作为对象属性名(key):

Symbol类型的key是不能通过Object.keys()或者for...in来枚举, 利用该特性,我们可以把一些不需要对外操作和访问的属性使用Symbol来定义。当使用JSON.stringify()将对象转换成JSON字符串的时候,Symbol属性也会被排除在输出内容之外。

获取以Symbol方式定义的对象属性:

// 使用Object的API 
Object.getOwnPropertySymbols(obj) // [Symbol(name)] 
// 使用新增的反射API 
Reflect.ownKeys(obj) // [Symbol(name), 'age', 'title']

创建私有属性:

const _name = Symbol('name'); 
class Person { 
         constructor(name) { 
                 this[_name] = name; 
         } 
         getName() { 
                 return this[_name]; 
         } 
} 
const person = new Person('Tom'); 
console.log(person.getName()); // Tom 
console.log(person._name); // undefined 

 

2. 闭包

一个函数和对其周围状态的引用捆绑在一起,闭包让你可以在一个内层函数中访问到其外层函数的作用域。内层的作用域访问它外层函数作用域里的参数/变量/函数时,闭包就产生了。

闭包的作用:1、读取函数内部的变量;2、让这些变量始终保持在内存之中。

应用场景:封闭作用域,延长变量寿命。具体如函数返回,getter/setter, 赋值,函数节流等

 

3. DOM的事件机制

addEventListener() 默认监听冒泡事件,将第三个参数传入true,则为捕获事件

event.stopPropagation();  // 停止冒泡或捕获

不会冒泡、捕获的事件:scroll,focus/blur, mouseleave/mouseenter, Media 事件(如onplay,onpause等)

 

4. 原型和原型链

原型:

在 JavaScript 中,每当定义一个对象时候,对象中都会包含一些预定义的属性。其中每个函数对象都有一个prototype 属性在constructor中,这个属性指向函数的原型对象,它对所有对象实例共享它所包含的属性和方法。

原型链:

原型链是原型对象创建过程的历史记录,当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,如果还没有找到就会再在构造函数的prototype的__proto__中查找,这样一层一层向上查找就会形成一个链式结构

 

5. 设计模式 

 

单例模式:

一个类只有一个实例,并提供一个访问他的全局访问点。比如VueX,使用一个全局的store用来存储应用的所有状态。

工厂模式:

根据不同的参数,返回不同类的实例。将对象的创建与对象的实现分离,实现复杂,但使用简单。工厂会给我们提供一个工厂方法,我们直接去调用即可。

适配器模式:

用于解决兼容问题,接口/方法/数据不兼容,将其转换成访问者期望的格式进行使用。

装饰器模式:

在不改变原对象的基础上,增加新属性/方法/功能。即一个对象被另一个对象包装。

策略模式:

定义一系列算法,根据输入的参数决定使用哪个算法。比如表单验证,替代if-else的做法,增加可复用性。

观察者模式:

如双向绑定的发布订阅者模式。get创建Watcher,set的时候通知watcher改变dom。

代理模式:

为不直接调用,通过一个代用品去控制它的访问。如HTML的点击事件代理。

外观模式:

为子系统的一组接口提供一个一致的界面,定义了一个高层接口,这个接口使子系统更加容易使用。如前端的封装浏览器兼容性判断的接口。

迭代器模式

提供一种方法顺序一个聚合对象中各个元素,而又不暴露该对象的内部表示。如forEach, es6的Iterator。

原型模式:

就是通过构造函数的prototype, 指向创建对象的种类,并且通过拷贝这些原型创建新的对象。

 

6. ES6运算符

可选链操作符(?.):

a?.b  // 等同于a == null ? undefined : a.b
a?.[x]  // 等同于a == null ? undefined : a[x]
a?.b()  // 等同于a == null ? undefined : a.b()
a?.()  // 等同于a == null ? undefined : a()
let res = week ?. tuesday ?. location; 
// 等价 let res = week && week.tuesday && week.tuesday.location

空值合并操作符(??):

仅当左侧为 null 或者 undefined 时,返回其右侧值,否则返回左侧值。区别于( || )。 

null ?? 5 // => 5
undefined ?? 5 // => 5
"" ?? 5 // => ""

 空赋值运算符(??=):

let a = 0;
a ??= 1;
console.log(a); // 0
 
let b = null;
b ??= 1;
console.log(b); // 1

 

7. TypeScript

TypeScript 是拥有类型语法的 JavaScript,是强类型编程语言。

优点:

代码可预测,更早发现 BUG

提供一些面向对象的写法,支持接口、抽象类、枚举等面向对象语言的特性

提供可选的强静态类型,同时提供any类型可以做一些宽松兼容

缺点:

学习成本、要编译、Any类型、代码量更大

 

相关知识点:

泛型:指定一个T类型,T为用户自定义

function identity<T>(arg: T): T {
    return arg;
}
identity<string>('hello');

type类型别名不仅可以用来表示基本类型,还可以用来表示对象类型、联合类型、元组和交集。

type userName = string; // 基本类型 type userId = string | number; // 联合类型 type arr = number[];  // 对象类型 
type Person = {     
         id: userId;
         name: userName; 
         age: number; 
         gender: string;
         isWebDev: boolean; 
};
// 泛型 type Tree<T> = { value: T }; 
const user: Person = { 
         id: "901",     
         name: "椿",     
         age: 22,     
         gender: "女",     
         isWebDev: false, 
}; 
const numbers: arr = [1, 8, 9];

enum: 枚举

enum Color {
    Red,
    Blue=3,
    Green
}
console.log(Color.Red);  //0
console.log(Color.Blue);  //3

 

posted @ 2023-10-31 23:08  h2303  阅读(30)  评论(0)    收藏  举报