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

《ECMAScript 6 入门 第二版》读书会笔记 #8

Open
loveky opened this issue Jul 10, 2017 · 27 comments
Open

《ECMAScript 6 入门 第二版》读书会笔记 #8

loveky opened this issue Jul 10, 2017 · 27 comments

Comments

@loveky
Copy link
Owner

loveky commented Jul 10, 2017

No description provided.

@kumamio
Copy link

kumamio commented Jul 13, 2017

chapter1:

GET:

1. 使nodejs环境支持ES6语法,并进行调试。
step:
1)安装es-checker
2)安装babel,以及创建一个.babelrc的配置文件 ,安装babel-preset-es2015
3)在nodejs下测试es6代码,并查看es5转码。

2. 运行Webpack环境,并进行es6代码的调试
step:
1)clone买什么项目,安装webpack ,yarn, 及其依赖。
2)webpack.config.js 一些参数及路径
3) package.json 一些参数及命令
4) 转码入口jsx文件。

Q:

  1. babel src -d lib //编译整个src文件夹并输出到lib文件夹中
    如果是编辑一个文件下的多个文件夹下的js怎么写?
  2. package.json 是不是npm 与yarn 共用一个的配置文件 ?

chapter2:

GET:

  1. 块级作用域
const t = 3;
if(true){
	const t = 5
}
t   // 3
  1. let 与 const 一样,不可重复声明
let s = 3;
let s = 5;  // Uncaught SyntaxError: Identifier 's' has already been declared at <anonymous>:1:1

3.块级作用域的出现,实际上使得获得广泛应用的立即执行匿名函数(IIFE)不再必要了。

(function () {
    var tmp = ...;
    ...
}());

{
    let tmp = ...;
    ...
}

@Onlyfor3ver
Copy link

Onlyfor3ver commented Jul 14, 2017

1、babel5版本默认包含各种转换插件,然而babel6.X相关转换插件需要自己下载。 babel-preset-es2015包含了所有插件,因此需要安装之后才能使用babel做到转换。但是babel只能转换ES6的语法,不能转换新的API,如Promise已经一些定义在全局上的方法例如:Object.assign。这时就得通过别的方法:1、babel-runtime 2、bable-polyfill
2、另外为了兼容性 要引入es5-shim和es5-sham。两者的区别:shim可以模拟ES5中可以被模拟的方法。sham是那些无法被模拟的方法,sham就尽力去模拟,只承诺不崩溃,不承诺是否有效。sham依赖于shim。https://github.com/es-shims/es5-shim
3、在IE8下,使用关键字或者保留字作为对象的属性值 例如 xxx.catch 会报错。 解决方法是 xxx['catch'] 或者引入 插件来处理
transform-es3-property-literals 和 transform-es3-member-expression-literals
4、let只在代码块中有效。不存在变量提升。相同作用域内,不允许重复声明。
5、ES5只有全局作用域和函数作用域,会导致 1、内层变量覆盖外层变量 2、用来计数的循环变量泄露为全局变量。
6、ES6的块级作用域允许声明函数只在使用大括号的情况下成立,如果未使用大括号,会报错
7、var 和 function 声明的全局变量 依旧是全局对象的属性。let const class 声明的全局变量 不属于全局对象的属性。

chapter3
1、function* fibs(){
var a = 0;
var b = 1;
while(true) {
yield a;
[a , b] = [b , a + b];
}
}
var [first,second,third,fourth,fifth,sixth] = fibs();
undefined
first //0
second //1
third //1
fourth //2
fifth //3
sixth //5
a 0 b 1
a 1 b 1
a 1 b 2
a 2 b 3
a 3 b 5
a 5 b 7

2、在es6内部使用严格相等运算符,判断一个位置是否有值。所以一个数组成员不严格等于undefined,默认值是不会生效的。
3、对象的解构与数组 有一个重要的不同,数组的元素时按次序排列的,对象的属性没有次序,变量必须与属性同名。
4、
image

对象的解构赋值的内部机制,是先找到同名属性,然后再赋值给对应的变量。真正被赋值的是后者,而不是前者。

@fannyCai
Copy link

fannyCai commented Jul 14, 2017

第二章 let和const命令

let
let声明一个变量,只在let命令所在的代码块有效
暂时性死区:在代码块内使用let命令声明变量之前,该变量都是不可用的
let 不允许在相同作用域内重复声明同一个变量
可以使用let很方便实现块级作用域(IIFE)

const

const用来声明常量。一旦声明,其值就不能改变,一旦声明必须立即初始化,不能留到以后赋值
复合类型的变量,const只存储地址,内部值可以变化(Object.freeze() 冻结对象)

let,const,class 声明的全局变量不属于全局对象的属性

第三章 变量的解构赋值

解构:es6允许按照一定模式,从数组或对象中提取值,对变量进行赋值
模式匹配:等号两面的模式相同,左边的变量赋予对应的值

数组的解构

1、解构失败时,不成功的值等于undefined
2、允许不完全解构
3、解构赋值允许默认值存在,=右边必须是undefined
4、如果等号的右边不是数组,会报错

对象的解构

对象的解构赋值:先找到同名属性,然后再赋给对应的变量
对象的解构常用语对象方法的赋值
let { sin, cos } = Math;

数值和布尔值的解构会转为对象
const {toString :s} = true;

undefined 也会触发函数参数的默认值

解构的用途:
1、交换变量的值
2、从函数返回多个值
3、函数参数的定义
4、json数据提取
5、函数参数的默认值
6、遍历Map结构
7、输入模块的指定方法

@maplehongye
Copy link

Get:
1、ECMAScript的历史与混乱的版本命名(参考资料
2、IT名词了解:交互式运行环境(REPL),babel和nodejs的REPL环境都支持es6

3、E C M A S c r i p t和 J a v a S c r i p t的关系是 ,前者是后者的规格 ,后者是前者的一种实现

4、E S 6明确规定 ,如果区块中存在 l e t和 c o n s t命令 ,则这个区块对这些命令声明的变量从一开始就形成封闭作用域 。只要在声明之前就使用这些变量 ,就会报错 。这在语法上称为 “暂时性死区 ” ( t e m p o r a l d e a d z o n e ,简称 T D Z ) 。暂时性死区的本质就是 ,只要一进入当前作用域 ,所要使用的变量就已存在 ,但是不可获取 ,只有等到声明变量的那一行代码出现 ,才可以获取和使用该变量 。

5、l e t不允许在相同作用域内重复声明同一个变量 。

6、需要注意的是 ,如果在严格模式下 ,函数只能在顶层作用域和函数内声明 ,其他情况 (比如 i f代码块 、循环代码块 )下的声明都会报错 。

7、对于复合类型的变量 ,变量名不指向数据 ,而是指向数据所在的地址 。 c o n s t命令只是保证变量名指向的地址不变 ,并不保证该地址的数据不变 ,所以将一个对象声明为常量必须非常小心 。

8、E S 5只有两种声明变量的方法 : v a r命令和 f u n c t i o n命令 。 E S 6除添加了 l e t和 c o n s t命令 ,后面章节还会提到另外两种声明变量的方法 : i m p o r t命令和 c l a s s命令 。所以 , E S 6一共有 6种声明变量的方法 。

9、const 用来 声明 常量。 一旦 声明, 其 值 就不 能改变。
对于 复合 类型 的 变量, 变量 名 不 指向 数据, 而是 指向 数据 所在 的 地址。 const 命令 只是 保证 变量 名 指向 的 地址 不变, 并不 保证 该 地址 的 数据 不变, 所以 将 一个 对象 声明 为 常量 必须 非常 小心。

@hanyuxinting
Copy link

hanyuxinting commented Aug 4, 2017

4 字符串扩展

理解使用场景。
和为什么会出现这样的接口?

考虑一些不能被unicode识别的中文,需要用codePointAt()\fromCodePoint()\At()\遍历器接口;
关于字符串是否包含在另一个字符串中的方法:


var s = 'Hello world!';
s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true


var s = 'Hello world!';
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false

重复字符串的方法:repeat
如果是整数,正的即为重复次数,负的报错。
如果是小数,忽略小数点及后数据。
-1-0为0
重复0次,就是不展示该串。
NaN为0;
Infinity 则报错。
字符串?先字符串转化为数字。

使用方法:
'str'.repeat(2.7); //'strstr' 'str'.repeat('s'); // ''

字符串补齐:
数值补齐和日期补齐~~~着重,其他就是各种被字符串补齐

'1'.padStart(10, '0') // "0000000001"
'12'.padStart(10, '0') // "0000000012"
'123456'.padStart(10, '0') // "0000123456"
'12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'

'abc'.padStart(10, '0123456789')
// '0123456abc'

模板字符串-我喜欢。。

老:

$('#result').append(
'There are <b>' + basket.count + '</b> ' +
'items in your basket, ' +
'<em>' + basket.onSale +
'</em> are on sale!'
);

新:

$('#result').append(`
There are <b>${basket.count}</b> items
in your basket, <em>${basket.onSale}</em>
are on sale!
`);
//  普通字符串
`In JavaScript '\n' is a line-feed.`
//  多行字符串
`In JavaScript this is
not legal.`
console.log(`string text line 1
string text line 2`);
//  字符串中嵌入变量
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`

当然这样就不可避免的出现行内的空格和行首行尾的空格,行尾行首可以用 trim 去掉~

$('#list').html(`
<ul>
<li>first</li>
<li>second</li>
</ul>
`.trim());

模板引用变量的方式,可以联想trimpath、vm的语法,类似~
不仅可以引用变量,还可以进行运算,甚至可以调用函数~

var x = 1;
var y = 2;
`${x} + ${y} = ${x + y}`
// "1 + 2 = 3"

`${x} + ${y * 2} = ${x + y * 2}`
// "1 + 4 = 5"

var obj = {x: 1, y: 2};
`${obj.x + obj.y}`
// 3

function fn() {
return "Hello World";
}
`foo ${fn()} bar`
// foo Hello World bar

嵌套方式:


const tmpl = addrs => `
<table>
${addrs.map(addr => `
<tr><td>${addr.first}</td></tr>
<tr><td>${addr.last}</td></tr>
`).join('')}
</table>
`;

const data = [
{ first: '<Jane>', last: 'Bond' },
{ first: 'Lars', last: '<Croft>' },
];
console.log(tmpl(data));

Q:
如果大括号中的值不是字符串,将按照一般的规则转为字符串。比如,大括号中是一个对象,将默认调用对象的toString方法。??

数组的扩展

Array.from方法用于将两类对象转为真正的数组:类似数组的对象( array-like object )和可遍历( iterable )的对象(包括 ES6 新增的数据结构 Set 和
Map )。
类似数组的对象,本质特征只有一点,即必须有length属性。

任何有length属性的对象,都可以通过Array.from方法转为数组,而此
时扩展运算符就无法转换。

let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
// ES5 的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6 的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']

可以批量给素材改样式么。。

// NodeList 对象
let ps = document.querySelectorAll('p');
Array.from(ps).forEach(function (p) {
console.log(p);
});
// arguments 对象
function foo() {
var args = Array.from(arguments);
// ...
}
Array.from('hello')
// ['h', 'e', 'l', 'l', 'o']
let namesSet = new Set(['a', 'b'])
Array.from(namesSet) // ['a', 'b']

扩展运算符的功效:
扩展运算符背后调用的是遍历器接口(Symbol.iterator)

// arguments 对象
function foo() {
var args = [...arguments];
}
// NodeList 对象
[...document.querySelectorAll('div')]
[...'hello']
// ["h", "e", "l", "l", "o"]

Array.from({ length: 3 });
// [ undefined, undefined, undefined ]

替代方案:

const toArray = (() =>
Array.from ? Array.from : obj => [].slice.call(obj)
)();
Array.from(arrayLike, x => x * x);
//  等同于
Array.from(arrayLike).map(x => x * x);
Array.from([1, 2, 3], (x) => x * x)
// [1, 4, 9]

把一组值转化成数组

是弥补数组构造函数Array()的不足
Array.of基本上可以用来替代Array()或new Array()

Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1

Array.of() // []
Array.of(undefined) // [undefined]
Array.of(1) // [1]

typeof(Array.of(undefined)[0])
// "undefined"
function ArrayOf(){
return [].slice.call(arguments);
}

数组的copyWithin

Array.prototype.copyWithin(target, start = 0, end = this.length)

[1, 2, 3, 4, 5].copyWithin(0, 3)
// [4, 5, 3, 4, 5]

数组实例的find方法,用于找出第一个符合条件的数组成员。


[1, 4, -5, 10].find((n) => n < 0)
// -5


[1, 5, 10, 15].find(function(value, index, arr) {
return value > 9;
}) // 10

[1, 5, 10, 15].findIndex(function(value, index, arr) {
return value > 9;
}) //2

[NaN].indexOf(NaN)
// -1
[NaN].findIndex(y => Object.is(NaN, y))
// 0

 Object.is(NaN, NaN)
//true

fill

fill方法使用给定值,填充一个数组。

['a', 'b', 'c'].fill(7)
// [7, 7, 7]
new Array(3).fill(7)
// [7, 7, 7]

['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']

['a', 'b', 'c'].fill(7, 1)
//["a", 7, 7]

遍历数组

entries(),keys()和values()
可以
用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。

for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1

//其实并不支持目前的浏览器~~~
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b"
let letter = ['a', 'b', 'c'];
let entries = letter.entries();
console.log(entries.next().value); // [0, 'a']
console.log(entries.next().value); // [1, 'b']
console.log(entries.next().value); // [2, 'c']

includes

Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。

[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
[1, 2, NaN].includes(NaN); // true
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true

indexOf方法有两个缺点,一是不够语义化,它的含义是找到参数值的第一个出现位置,所以要去比较是否不等于 -1 ,表达起来不够直观。二是,它内
部使用严格相当运算符( === )进行判断,这会导致对NaN的误判。

[NaN].indexOf(NaN)
// -1

[NaN].includes(NaN)
// true

@Onlyfor3ver
Copy link

Onlyfor3ver commented Aug 4, 2017

1、ES6为字符串提供了遍历器接口,使得字符串可以被 for 。。of循环遍历,该遍历器最大的优点是识别大于0xFFFF的码点
2、通过polyfill可以使用at()方法 该方法可以识别大于0xFFFF的字符 返回正确的字符。
3、includes() 返回布尔值 表示是否找到了参数字符串 startsWith() endsWith() 三种方法都有第二个参数 n endsWith的参数代表前n个字符查找 includes 和 startsWith代表第n个位置知道字符串结束
4、padStart用于头部补全,padEnd用于尾部补全。接受两个参数 第一个是用来指定字符串的最小长度 第二个参数是用来补全的字符串,省略第二个参数则用空格补全
image
image
1、Array.from 用于将两类对象转为真正的数组:类似数组的对象(本质有一点,即必须有length属性,这种对象不能用扩展运算符来转换数组) 和 可遍历的对象
2、扩展运算符背后调用的是遍历器接口。因此扩展运算符可以将某些数据(nidelist)结构转为数组。
3、Array.from接受第二个参数,相当于数组的map方法,用于对数组的每个元素进行操作。将处理后的值返回给数组。
4、Array.of 总是返回参数值组成的数组,如果没有参数,就返回一个空数组
5、copyWith方法在当前数组内部,将指定位置的成员复制到其他位置,返回当前数组。
Array.prototype.copyWithin(target, start = 0, end = this.length) target必选 从该位置开始替换数组 start 从该位置读取数据 end 表示到该位置停止读数据
6、fill()方法使用给定值,填充一个数组。fill方法可以接受三个参数,第一个参数为填充值 第二个参数为填充的起始位置 第三个参数为结束为止
7、 entries()是对键值对的遍历 keys()是对键名的遍历 values()是对键值的遍历
8、Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值。第二个参数表示搜索的起始位置,默认为0
9、map结构的has方法是用来查找键名 set结构的has方法是用来查找值。
10、
forEach filter every some 都会跳过空位
map会跳过空位 ,但是会保留值
join和toString会将空位视为undefined 而undefined和null会被处理成空字符串
Array.from 方法会将数组的空位转为undefined
扩展运算符会将量空位转为undefined
copyWith会将空位一起拷贝
fill会将空位视为正常的数组位置
for of 会遍历空位
entries keys values find findIndex都会将空位处理成undefined

@kumamio
Copy link

kumamio commented Aug 4, 2017

Chapter 4:字符串的扩展
Q:
1.

var a = 5;
var b = 10;
tag`Hello ${ a + b } world ${ a * b }`;
// 等同于
tag(['Hello ', ' world ', ''], 15, 50);

Chapter 7:数组的扩展
G:

  1. Array.from
Array.from({length: 5}, (v, i) => i)

let ps = document.querySelectorAll('p');
Array.from(ps).forEach(function (p) {
console.log(p);
});

function foo() {
var args = [...arguments];
}
2.
扩展运算符(...)可用于iterator接口的对象转换为数组 。
3. copyWithin 方法
[1, 2, 3, 4, 5].copyWithin(0, 3, 4)
['a', 'b', 'c'].fill(7, 1, 2)
[1, 5, 10, 15].findIndex(function(value, index, arr) {
return value > 9;}) // 2
[1, 4, -5, 10].find((n) => n < 0)

@fannyCai
Copy link

fannyCai commented Aug 7, 2017

字符串的扩展

1.includes(),startsWith(),endWith()
includes():返回布尔值,表示是否找到了参数字符串。
startsWith():返回布尔值,表示参数字符串是否在源字符串的头部。
endsWith():返回布尔值,表示参数字符串是否在源字符串的尾部。
支持第二个参数,表示开始搜索的位置,endsWith它针对前n个字符

2、repeat方法返回一个新字符串,表示将原字符串重复n次

3、padStart().padEnd()
padStart用于头部补全,padEnd用于尾部补全

4、模板字符串
string ${变量}

数组的扩展

1、Array.from()
Array.from(arrayLike[, mapFn[, thisArg]])

2、Array.of():将一组数值转换为数组

3、copyWithin(),复制数组的一部分到同一数组中的另一个位置,并返回它,而不修改其大小,会修改原数组
Array.prototype.copyWithin(target, start = 0, end = this.length)

4、 find() 方法返回数组中满足提供的测试函数的第一个元素的值
findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。
[NaN].findIndex(y => Object.is(NaN, y))

5、fill()方法,使用给定值填充数组

6、数组实例的entries()、keys()、和values()方法,主要用来遍历数组,keys()是对键名的遍历,values()是对键值的遍历,entries()是对键值对的遍历

var arr = ["a", "b", "c"];
var iterator = arr.entries();
for (let e of iterator) {
    console.log(e);
}

7、Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值
8、数组的空位 处理规则不同意,尽量避免空位

@Onlyfor3ver
Copy link

1、funciton m1({x = 0, y = 0} = {}) {return [x,y]} function m2({x , y} = {x:0 , y: 0}) {return [x,y]}
m1 参数的默认值是空对象 但是指定了 解构的默认值 m2 函数的默认值是具体属性的对象 但是 没有设置解构的默认值
2、null无法触发默认值
3、设置了默认值以后,函数的length属性将返回没有指定默认值的参数个数。 如果设置了默认值得参数不是尾参数 ,那么length属性也不再计入后面的参数。
4、rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。rest参数必须为最后一个参数。函数的length属性 不包括rest参数。
5、spread运算符是三个点 好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列。
6、如果将扩展运算符用于数组赋值,只能放到参数的最后一位,否则会报错。
const [aaa,...bba,cc]= [1,2,3,4]
7、箭头函数不能用作Generator函数。
8、箭头函数的this绑定定义时所在的作用域,普通函数的this指向运行时所在的作用域。
9、函数表达式中,es5中的name为空 es6中的名字为赋值的变量名
image

@hanyuxinting
Copy link

hanyuxinting#13

@fannyCai
Copy link

函数的扩展

rest参数

function push(array,...items){
array.push(...items)
}
Math.max(...[14,3,7])

合并数组
[...arr1,...arr2]
解构赋值结合
const [first,...rest] = [1, 2, 3, 4, 5]
转化类数组的对象

var nodelist = document.querySelectorAll('div');
var array = [...nodelist]

箭头函数
1、函数体内的this对象就是定义是所在的对象
2、不可以试用arguments对象,可以用rest代替
3、不可以用当做构造函数,即不可以用new命令

@Onlyfor3ver
Copy link

1、ES5只能使用 var obj = {foo:true} es6可以 let a = 'a' let obj = {[a]:true} //属性简洁表示法
2、表达式还可以定义方法名 let obj = {['h' + 'ello'] () {return 'hi';} } obj.hello() //hi
3、属性名表达式与简洁表示法 不能同时使用 var foo = 'bar' ; var baz = {[foo]}
4、Object.is()用于判断严格相等 与 === 不一致的地方有两点 Object.is(+0,-0) false Object.is(NaN,Nan) true
5、Object.assign用于对象的合并,将源对象的所有可枚举属性,复制到目标对象。实行的是浅拷贝。
6、es5有三个操作会忽略enumerable为false的属性:
for ... in 之遍历对象自身的和继承的可枚举属性
Object.assign() 返回对象自身的所有可枚举的属性的键名
JSON.stringify() 只串行化对象自身的可枚举的属性
Object.assign() 只拷贝对象自身的可枚举属性
for in 会返回继承的属性。
7、Object.entries 方返回一个数组,成员是参数对象自身的(不包含继承的)所有可遍历属性的键值对数组
8、Object.keys(obj) 返回一个数组 包括对象自身的所有可枚举属性
Object.getOwnPropertyNames(obj) 返回一个数组 包含对象自身的所有属性 不包含Symbol属性 但是包括不可枚举属性
Object.getOwnPropertySymbols(obj) 返回一个数组 包含对象自身的所有Symbol属性
Reflect.ownKeys(obj) 返回一个数组 包含对象自身的所有属性。
遍历次序规则: 首先遍历所有属性名为数值的属性,按照数字排序 其次遍历所有属性名为字符串的属性,按照生成时间排序 最后遍历所有属性名为Symbol值的属性,按照生成时间排序

@fannyCai
Copy link

对象的扩展

1、对象中允许只写属性名,不写属性值,属性值等于属性名代表的变量
2、 属性名表达式与简洁表示法不能同时使用,否则会报错
3、Object.is()用来比较两个值是否严格相等,与严格等(===)的行为基本一致,不同之处只有两个

    1. +0不等于-0
    1. NaN等于自身

4、Object.assign() 将源对象的所有的可枚举属性复制到目标对象
如果目标对象与源对象有同名属性,后面的属性会覆盖前面的属性

  • 1、Object.assign 只复制自身属性,不可枚举的属性和继承的属性不会被复制
  • 2、对于嵌套的对象,处理方法是替换,而不是添加
  • 3、Object.assign 处理数组,会将视为对象

@kumamio
Copy link

kumamio commented Aug 18, 2017

1.ES6允许在对象之中, 只写属性名, 不写属性值。 这时, 属性值等于属性名所代表的变量。
2.( 1) for...in
for...in循环遍历对象自身的和继承的可枚举属性( 不含Symbol属性) 。
( 2) Object.keys(obj)
Object.keys返回一个数组, 包括对象自身的( 不含继承的) 所有可枚举属性( 不含Symbol属性) 。
( 3) Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames返回一个数组, 包含对象自身的所有属性( 不含Symbol属性, 但是包括不可枚举属性) 。
( 4) Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols返回一个数组, 包含对象自身的所有Symbol属性。
( 5) Reflect.ownKeys(obj)
Reflect.ownKeys返回一个数组, 包含对象自身的所有属性, 不管是属性名是Symbol或字符串, 也不管是否可枚举。
3.Object.setPrototypeOf()

@fannyCai
Copy link

Set 和Map 数据结构

Set 类似数组,单成员的值是唯一的,没有重复的值
image

属性和方法

  • add(value) 添加某个值,返回Set结构本身
  • delete(value) 删除某个值,返回一个布尔值,表示删除是否成功
  • has(value) 返回一个布尔值,表示参数是否为Set的成员
  • clear() 清除所有成员,没有返回值

遍历操作

  • keys() 返回一个键名的遍历器
  • values() 返回一个键值的遍历器
  • entries() 返回一个键值对的遍历器
  • forEach() 使用回调函数遍历每个成员

由于Set结构没有键名,只有键值,所有keys和values方法的行为完全一致

image
简洁去重
image

遍历中需要改变Set结构
`
let set3 = new Set([1, 2, 3]);
set3 = new Set([...set3].map(val => val*2 ))

let set4 = new Set([1, 2, 3]);
set4 = new Set(Array.from(set4,val => val*2))
`
WeakSet

不重复的值得集合,成员只能是对象,不能是其他类型的值,WeakSet的对象都是弱引用,成员无法引用,不可遍历

Map

Map 类似于对象,也是键值对的集合,“键” 的范围不限于字符串,可以是各种类型的值(包括对象)

Map 也可以接受一个数组作为参数,该数组的成员是一个个表示键值对的数值

image

如果对一个键多次赋值,后一次的值会覆盖前一次的值
如果读取一个未知的键,则返回undefined
只有对同一个对象的引用,Map结构才将其视为同一个键,同样的值的两个实例,在Map结构中视为两个键
如果Map 的键是一个简单类型的值(数字,字符串,布尔值),则只要两个值严格相等,Map就将其视为一个键,包括0,-0,NaN

实例的属性和操作方法

  • size 返回Map结构的成员总数
  • set(key,value) set方法设置key 所对应的键值,然后整个Map结构,如果Key 已经有值,则键值会被更新,否则生成新的该键
  • get(key) 读取对应的键值,如果找不到返回undefined
  • has(key) 返回一个布尔值,表示某个键是否存在
  • delete(key) 删除某个键
  • clear() 清除所有成员,没有返回值

遍历操作

  • keys() 返回一个键名的遍历器
  • values() 返回一个键值的遍历器
  • entries() 返回一个键值对的遍历器
  • forEach() 遍历所有的成员

与其他类型数据结构的互相转换

var map = new Map([["name", "张三"], ["title", "Author"]])

1、转数组
[...map]
image

@Onlyfor3ver
Copy link

1、set内部认为两个NaN是相等的
2、set实例的方法有: add(value) delete(value) 返回布尔值,表示删除是否成功 has(value) 返回一个布尔值,表示该值是否为set成员 clear()清空所有成员,没有返回值
3、set的遍历操作 keys() 返回键名的遍历器 values() 返回键值的遍历器 entries() 返回键值对的遍历器 forEach() 使用回调函数遍历每个成员
4、WeakSet结构与Set类似,区别在于 weakset的成员只能是对象,而不是其他类型的值 其次 weakset中的对象都是弱引用 即垃圾回收机制不考虑weakset对该对象的引用。也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象是否还在weakset中。
5、 Object是字符串-值 map结构是 值-值
6、map的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。map认为NaN相等,0 和 -0相等
7、size 返回map的成员总数 set(key,value) get(key) has(key) delete(key) clear()
8、map的遍历方法 keys values entries forEach

@kumamio
Copy link

kumamio commented Aug 28, 2017

Set 和 Map

1. set

G:

  1. add(value) , delete(value) , clear() , has()
  2. 遍历Set对象
    1). for (let x of set)
    2). set.forEach((value, key) => console.log(value * 2) )
    3), let arr = [...set]

Q:

1.对于dom的遍历

function divs () {
return [...document.querySelectorAll('div')] ;
}

[document.querySelectorAll('div')] 和 [...document.querySelectorAll('div')] 的区别
2.

var s = new Set([2,2,3,4])
s.keys() == s.values()  //true

key方法、 value方法、 entries方法返回的都是遍历器对象( 详见《 Iterator对象》 一章) 。 由于Set结构没有键名, 只有键值( 或者说键名和键值是同
一个值) , 所以key方法和value方法的行为完全一致。
3.[...set] 与 Array.from()差异

2. Map

G:

  1. 有delete, forEach, clear, has ,size, has ,keys方法 同Set对象, set 和 get 方法不同。

Q:

  1. Map 的键名可以是任何对象?
    2.var myMap = new Map();

var keyObj = {},
keyFunc = function () {},
keyString = "a string";

// 添加键
myMap.set(keyString, "和键'a string'关联的值");
myMap.set(keyObj, "和键keyObj关联的值");
myMap.set(keyFunc, "和键keyFunc关联的值");

myMap.delete(keyString) //true
myMap.values() //
image

@hanyuxinting
Copy link

hanyuxinting commented Sep 1, 2017

Get

有三类数据结构,自带Iterator神器。for of 默认会遍历。
数组、某些类似数组的对象,Set,Map。

let arr = ['a', 'b', 'c'];
arrSymbol.iterator
// arrSymbol.iterator
image

image

image

字符串的遍历器接口
重载~~

image

遍历器-线性处理。部署遍历器接口就是部署一种线性转换。
对象不支持。但是它可以当做Map呀。

类似数组和非类似。。
image

@Onlyfor3ver
Copy link

Onlyfor3ver commented Sep 1, 2017

1、
Iterator的作用有三个,一是为各种数据结构提供一个统一的简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是ES6创造了一种新的遍历命令for...of , Iterator接口主要供 for...of 。
2、
在ES6中,有三类数据结构原生具有Iterator接口:数组、某些类似数组的对象、Set和map结构。以上三类数据结构不需要自己写遍历器生成函数,for of会自动遍历他们,其他数据结构的Iterator接口,都需要自己在 Symbol.iterator属性上面部署,这样才会被for...of 循环遍历。
3、
解构赋值、扩展运算符、yield*、for of、Array.from、Map()、set()、weakMap()、weakSet()、Promise.all()、Promise.race() 等 默认调用Iterator
4、for in 有几个缺点:
1、数组的键名是数字 但是 for in循环是以字符串作为键名 '0'
2、for in 循环不仅遍历数字键名 还会遍历手动添加的其它键 包括原型链上的键
3、某些情况下 for in 循环会以任意顺序遍历键名

for in 不适合遍历数组 适合遍历对象。
5、 for of优点
1、有着不同于for in 一样的简洁语法 但是没有 for in的缺点
2、不同于forEach 他可以与break continue 和 return配合使用
3、提供了遍历所有数据结构的统一操作接口

Q:

对象部署遍历器接口不是很必要,因为这时对象实际上被当做map结构使用,那么能不能像类数组对象调用数组的Iterator方法一样,为对象调用例如map这样的数据结构的Iterator方法?

@fannyCai
Copy link

fannyCai commented Sep 1, 2017

GET
1、JavaScript 中迭代器是一个对象,提供一个next()方法,返回序列中的下一项,这个方法返回包含done和value两个属性的对象
2、string,Array,TypedArray,Map 和Set都是内置迭代器,它们原型中都有一个Symbol.iterator 方法
3、for...in 只能获得对象的键名,不能直接获取键值,for...of 允许遍历获得键值

@hanyuxinting
Copy link

hanyuxinting commented Sep 8, 2017

Get

next

next() 方法里的参数,是当做上一条yield返回值的。这个用来从外部不断注入数据。

image

V8引擎忽略第一次使用next的方法。。所以b的第一个next 和 c 的第一个next 返回结果一样~对y也没什么影响。

for...of

image

几种转化方法:

// 除了for...of循环以外,扩展运算符(...)、解构赋值和Array.from方法内部调用的,都是遍历器接口。这意味着,它们都可以将 Generator 函数返回的 Iterator 对象,作为参数

image

throw 方法

image

image

@Onlyfor3ver
Copy link

1、Generator函数是一个状态机,封装了多个内部状态。执行Generator函数会返回一个遍历器对象,依次遍历Generator内部的每一个状态/1、分段执行 2、可以控制阶段和每个阶段的返回值 3、可以知道是否执行到结尾。
2、yield本身没有返回值,或者总是返回undefined next方法可以带一个参数,该参数会被当做上一个yield的返回值。next的用途可以在Generator函数运行之后,继续向函数体内部注入值。
3、一旦Generator执行过程中抛出错误,且没有被内部捕获,就不会再执行下去,如果此后还调用next方法,将返回一个value属性等于undefined done属性等于true的对象。
4、如果Genetator函数内部有try finally块 那么return 方法会推迟到finally代码块执行完再执行。
5、yield*语句 用来在一个generator函数里面执行另外一个generator
6、 如果g函数的return语句后面依然有yield,则return后面的yield是白写
7、如果g函数没有yield和return 则第一次next就返回{ value:undefined,done:true}
8、如果g函数只有return 则第一次调用返回{ value:xxx,done:true} xxx为return的返回值,之后{ value:undefined,done:true}
9、同一个函数的不同遍历器互不干扰

@fannyCai
Copy link

fannyCai commented Sep 8, 2017

Generator 函数返回遍历器对象,只有调用next方法才会遍历下一个内部状态。yield表达式 暂停表达式
1、遇到yidld表达式,就暂停执行后面的操作,并将跟在yield后面的那个表达式的值,作为返回的额对象的valued属性值
2、下一次调用next方法是,再继续往下执行,直到遇到下一个yield表达式
3、如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回对象的value属性值
4、如果该函数没有return语句,则返回的对象的value属性值为undefined
5、yield 表达式后面的表达式,只有当调用next方法,内部指针指向该语句是才会执行

@Onlyfor3ver
Copy link

1、Genetator函数返回的是一个状态机,因此没有this对象,想要调用this则需要动态绑定
2、Promise也有一些缺点,1.无法取消promise, 一旦创建就会立即执行。2. 如果不设置回到函数,Promise内部抛出的错误 不会反应到外部。 3. 当处于pending状态时,无法得知目前进展到哪一个阶段。
3、如果Promise状态变成了Resolved 在抛出错误是无效的
4、catch方法返回的还是一个promise对象,因此还可以接着调用then方法。
5、Promise.all 方法的参数可以不是数组,但必须具有Iterator接口,且返回的每个成员换都是Promise实例。
6、Promise.race() 只要有一个实例状态改变,则将该实例传递给回调函数继续执行。
7、立即resolve的Promise对象,是在本轮事件循环的结束时,而不是在下一轮事件循环的开始时。

@fannyCai
Copy link

fannyCai commented Sep 18, 2017

Promise 三种状态

  • pending:初始值
  • resolved 已完成
  • Rejected 已失败

Promise实例生成以后,可以用then方法指定resolved状态和reject状态的回调函数,Promise新建后就会立即执行。而then方法中指定的回调函数,将在当前脚本所有同步任务执行完才会执行
image

API

Promise.prototype.then()

job1.then(job2).then(job3).catch(handleError);
每次调用then都会返回一个新创建的promise对象,而then内部只是返回的数据

Promise.prototype.catch()

Promise.all()

方法接受一个数组(或具有Iterator接口)作参数,数组中的对象(p1、p2、p3)均为promise实例,它的状态由这三个promise实例决定,这多个 promise 是同时开始、并行执行的

Promise.race()

方法同样接受一个数组(或具有Iterator接口)作参数。当p1, p2, p3中有一个实例的状态发生改变(变为fulfilled或rejected),p的状态就跟着改变。并把第一个改变状态的promise的返回值,传给p的回调函数

Q:

console.log(1);
new Promise(function (resolve, reject){
    reject();
    setTimeout(function (){
        resolve();            
    }, 0);
}).then(function(){
    console.log(2);
}, function(){
    console.log(3);
});
console.log(4);

@kumamio
Copy link

kumamio commented Sep 18, 2017

  1. promise的status
    image
  2. promise的链式调用
    image
  3. Promise.all方法
    image

@Onlyfor3ver
Copy link

Onlyfor3ver commented Sep 20, 2017

var Thunk = function (fn) {
    return function (...args) {
        return function (callback) {
            return fn.call(this, ...args, callback);
        }
    }
}
function f(a, cb) {
    cb(a);
}
var ft = Thunk(f);
var log = console.log.bind(console);
ft(1)(log)

var Thunk = function (fn) {
    return function (...args) {
        return function (callback) {
            return fn.call(this, ...args, callback);
        }
    }
}

function f(a, b, c, cb) {
    cb(a, b, c);
}
var ft = Thunk(f);
var log = console.log.bind(console);
ft(1, 2, 3)(log)

var Thunk = function (fn) {
    return function (...args) {
        return function (callback) {
            return fn.call(this, ...args, callback);
        }
    }
}

function f(...a, cb) {
    cb(...a);
}
var ft = Thunk(f);
var log = console.log.bind(console);
ft(1,2,3,44,55)(log)

var Thunk = function (fn) {
    return function (...args) {
        return function (callback) {
            return fn.call(this, callback , ...args);
        }
    }
}

function f(cb, ...a) {
    cb(...a);
}
var ft = Thunk(f);
var log = console.log.bind(console);
ft(1,2,3,555)(log)

var Thunk = function (fn) {
    return function (...args) {
        return function (callback) {
            return fn.call(this, callback , ...args);
        }
    }
}

function f(cb, ...a) {
    for (var i of a) {
        cb(i);
    }
}
var ft = Thunk(f);
var log = console.log.bind(console);
ft(1,2,3,555)(log)

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

6 participants