Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

《深入理解ES6》笔记 #21

Open
lfb opened this issue Aug 5, 2019 · 0 comments
Open

《深入理解ES6》笔记 #21

lfb opened this issue Aug 5, 2019 · 0 comments

Comments

@lfb
Copy link
Owner

lfb commented Aug 5, 2019

第一章:块级作用域

  1. var、let、和 const 声明的特点?
  2. var、let、和 const 声明的区别?

使用 var 声明的变量是不存在块级作用域的,使用 var 声明的变量存在变量提升机制,也就是说通过 var 声明的变量,无论在哪里声明,都会提升到当前的作用域顶部声明的变量。

使用 let 和 const 的声明存在块级作用域。块级作用域指在声明的变量只在当前的作用域下有效,而外部是无法访问的。

let 和 const 声明的相同点:

  • 块级作用域
  • 不存在变量提升
  • 不能重复声明
  • 临时死区,如果在声明前读取这些变量会报错

let 和 const 声明的区别:

  • const 声明是一个常量
  • const 声明常量的同时就需要赋值
  • const 声明常量后不能修改

第二章:字符串

新增的方法

  • codePointAt( string ) 返回字符串的指定的位置码位
  • String.fromCodePoint( number ) 传入指定的位置码位返回一个字符串
  • normalize() 把字符串转换为国际标准化,参数有 NFC, NFD, NFKC, NFKD
  • includes( string ) 检测字符串中是否包含传入的字符,返回true和false
  • starsWith(string, @index) 从字符串头部 index string
  • endsWith(string, @index) 从字符串尾部 index 位置开始检测是否匹配传入的字符串 string
  • repeat( number ) 接收一个 number,运算结果让字符串重复的number次,结果不会影响原来的字符串
  • 模板字符串:hello world,作用:
    • 多行字符串
    • 基本的字符串
    • HTML 转义
  • 字符串占位符:字符串需要包含变量时:hello, ${username}!

es5的一些字符串方法

  • indexOf( string ) 从字符首位开始检测传入的 string 字符串的首次出现的位置
  • lastIndexOf( string ) 从字符尾部开始检测传入的 string 字符串的首次出现位置
  • charAt() 返回指定位置的字符
  • charCodeAt() 返回字符串的指定的位置码位
var str = '波波';

str.codePointAt(0); // 27874
String.fromCodePoint(27874); // '波'
str.normalize('NFC');  // '波波'
str.includes('波') // true

var str = 'bobobo!';
str.startsWith('o', 0); // false
str.startsWith('o', 1); // true

str.endsWith('!'); // true

var str = 'bo';
str.repeat(3); // 'bobobo'

var str = `hello
    world!
`
var str = `<h1>hello, ${username}</h1>`

第三章:函数

es6中函数的形参可以设置默认值

function makeRequest(usl, timeout = 2000, callback = function () {}) {
    // TODO
}

es6函数的默认参数对arguments对象保持分离

function getUserInfo(name, age = 10) {
    // 参数默认值不会影响到arguments的对象
    console.log(arguments); //[0: "bo", ..]
    console.log(arguments.length); // 1
}

getUserInfo('bo');

当定义函数的形参不确定时,可以使用es6可以传入不定参数,arguments对象也是能正确的工作

function getUserInfo(name, ...info) {
   console.log(name); // 'bobobo'
   console.log(info); // [18, 'codingmoneky]
   console.log(arguments); // ["bobobo", 18, "codingmonkey"]
}

getUserInfo('bobobo', 18, 'codingmonkey');

使用元属性 new.target 来检测函数是否被 new 关键字调用

function Person(name) {
    console.log(new.target === Person);

    if (typeof new.target !== 'undefined') {
        this.name = name;
        
    } else {
        throw new Error('必须通过 new 关键字调用Person函数')
    }
}

Person('bobobo'); // Error: 必须通过 new 关键字调用Person函数
new PPerson('bobobo'); // 通过

箭头函数:

  • 没有this,super,arguments和new.target绑定
  • 不能使用new关键字调用
  • 没有原型
  • 不可以改变this的绑定
  • 不支持arguments对象
  • 不支持重复的命名参数
let f1 = value => value // 定义一个箭头函数且返回value值,相当于:
var f1 = function(value) {
    return value;
} 

let fn2 = () => {
    return new Promise((resolve, reject) => {

    }).catch(err => {

    })
}

第四章:扩展对象的功能性

对象简写

let fn1 = (name, age) => {
    return {
        name, // 简写,不用写name: name
        age
    }
}

可计算属性名:

let user = {
    ['first name']: 'bobo'
}
console.log(user['first name']); // 'bobo'

新增的方法

  • Object.is(value1, value2): 比较2个值是否相等,和三等符合运算是一样的,特殊的地方:
    • Object.is(+0, -0) 为false
    • Object.is(NaN, NaN) 为true
  • Object.assign(target, source):把源对象复制一个目标对象(浅拷贝)
let target = {};
let source = {
    name: 'bobo',
    like: 'coding'
}
Object.assign(target, source);
console.log(target); // {name: "bobo", like: "coding"}

增强对象的原型

  • Object.getPrototypeOf( obj ) 获取指定的obj对象的原型
  • Object.setPrototypeOf(obj, prototype) 设置对象的原型,第一个参数为对象,第二个参数为设置第一个参数对象的原型对象
function Books(name) {
    this.name = name;
}

function Mobile(name) {
    this.name = name
}

let books = new Books('jsbooks');
Object.getPrototypeOf(books) === Books.prototype // true

// 手动设置books指向Mobile原型
Object.setPrototypeOf(books, Mobile.prototype);

// 设置后发现books的原型对象不再指向Books原型对象了,而是指向Mobile原型对象
Object.getPrototypeOf(books) === Books.prototype // false
Object.getPrototypeOf(books) === Mobile.prototype // true

第五章:解构

对象解构,取对象的值:

let user = {
    name: 'bobobo',
    email: 'itbo@163.com'
}

// 取 name 和 email 属性
let {name, email} = user;

// 如果对象 node 中没有 jobs 属性
let {name, email, jobs} = user;
// 那么 jobs 的值是 undefined,当然也可以赋默认值
let {name, email, jobs = 'codingmonkey'} = user;

// 解构取值且重新命名
let {name: username, email: workEmail} = user;

// 解构取值且重新命名且赋默认值
let {name: username, email: workEmail, jobs: myjobs = 'codingmonkey@yeah.net'} = user;

嵌套对象解构取值:

let node = {
    local: {
        start: {
            line: 1,
            column: 1
        },
        end: {
            line: 10,
            column: 10
        }
    }
};

// 取嵌套的 start 对象
let {local: {start}} = node;
console.log(start.line); // 1
console.log(start.column); // 1

// 取嵌套的 end 对象
let {local: {end}} = node;
console.log(end.line); // 10
console.log(end.column); // 10

// 取嵌套的 start 对象 且重新命名
let {local: {start: localStart}} = node;
console.log(localStart.line); // 1
console.log(localStart.column); // 1

// 取嵌套不存在的 middle 对象且赋值默认值
let {local: {middle = {line: 5, column: 5}}} = node;
console.log(middle.line); // 5
console.log(middle.column); // 5

数组解构

let arr = [1, 2, 3];
let [value1] = arr; 

console.log(value1)  // 1

// 默认值
let arr = [1];
let [value1, value2 = 2] = arr;

// 不定参数
let arr = [1, 2, 3, 4, 5];
let [value1, ...values] = arr;


// 函数不定参数解构
function getUserInfo(name, ...info) {
    // TODO
    let {age, like, jobs = 'codingmonkey'} = info;
}

第六章:Symbol

Symbol代表唯一的ID

// 创建Symbol
let name = Symbol();
let key = Symbol('keys');

const person = {
    [name]: 'bobobo',
    [key]: 'codingmoneky'
}

第七章:Set和Map

Set 类似数组,但Set不允许元素重复。

  • size:获取元素数量。
  • add(value):添加元素,返回 Set 实例本身。
  • delete(value):删除元素,返回一个布尔值,表示删除是否成功。
  • has(value):返回一个布尔值,表示该值是否是 Set 实例的元素。
  • clear():清除所有元素,没有返回值
const s = new Set();
s.add(1).add(2).add(2); // 添加元素

s.size // 2

s.has(1) // true
s.has(2) // true
s.has(3) // false

s.delete(2);
s.has(2) // false

s.clear();
console.log(s);  // Set(0) {}

// 去重
let arr = [1, 2, 3, 4, 3, 4, 5, 6, 6];
let set = new Set([...arr]);

Set 实例的遍历,可使用如下方法

  • keys():返回键名的遍历器。
  • values():返回键值的遍历器。不过由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys()和values()返回结果一致。
  • entries():返回键值对的遍历器。
  • forEach():使用回调函数遍历每个成员
let set = new Set(['aaa', 'bbb', 'ccc']);

for (let item of set.keys()) {
  console.log(item);
}
// aaa
// bbb
// ccc

for (let item of set.values()) {
  console.log(item);
}
// aaa
// bbb
// ccc

for (let item of set.entries()) {
  console.log(item);
}
// ["aaa", "aaa"]
// ["bbb", "bbb"]
// ["ccc", "ccc"]

set.forEach((value, key) => console.log(key + ' : ' + value))
// aaa : aaa
// bbb : bbb
// ccc : ccc

Map 的用法和普通对象基本一致,先看一下它能用非字符串或者数字作为 key 的特性。

Map 实例的属性和方法如下:

  • size:获取成员的数量
  • set(key, value):设置成员 key 和 value
  • get():获取成员属性值
  • has():判断成员是否存在
  • delete():删除成员
  • clear():清空所有
const map = new Map();
map.set('aaa', 100);
map.set('bbb', 200);

map.size // 2

map.get('aaa') // 100

map.has('aaa') // true

map.delete('aaa')
map.has('aaa') // false

map.clear()

Map 实例的遍历方法有

  • keys():返回键名的遍历器。
  • values():返回键值的遍历器。
  • entries():返回所有成员的遍历器。
  • forEach():遍历 Map 的所有成员
const map = new Map();
map.set('aaa', 100);
map.set('bbb', 200);

for (let key of map.keys()) {
  console.log(key);
}
// "aaa"
// "bbb"

for (let value of map.values()) {
  console.log(value);
}
// 100
// 200

for (let item of map.entries()) {
  console.log(item[0], item[1]);
}
// aaa 100
// bbb 200

// 或者
for (let [key, value] of map.entries()) {
  console.log(key, value);
}
// aaa 100
// bbb 200
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant