You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
functionafunc(){}// undefinednewafunc()afunc{}afunc=()=>{}()=>{}newafunc()// VM19499:1 Uncaught TypeError: afunc is not a constructor .at <anonymous>:1:1
consthandler={id: '123456',init(){document.addEventListener('click',e=>this.dosomething(e.type),false,);},dosomething(type){console.log(`handle ${type} for ${this.id}`);},};
classToggleextendsReact.Component{constructor(props){super(props);this.state={isToggleOn: true};// This binding is necessary to make `this` work in the callbackthis.handleClick=this.handleClick.bind(this);}handleClick(){this.setState(prevState=>({isToggleOn: !prevState.isToggleOn}));}render(){return(<buttononClick={this.handleClick}>{this.state.isToggleOn ? 'ON' : 'OFF'}</button>);}}ReactDOM.render(<Toggle/>,document.getElementById('root'));
classLoggingButtonextendsReact.Component{// This syntax ensures `this` is bound within handleClick.// Warning: this is *experimental* syntax.handleClick=()=>{console.log('this is:',this);}render(){return(<buttononClick={this.handleClick}>
Click me
</button>);}}
functionnext(ret){if(ret.done)returnresolve(ret.value);constvalue=toPromise.call(ctx,ret.value);if(value&&isPromise(value))returnvalue.then(onFullfilled,onRejected);returnonRejected(newTypeError(`You may only yield a function, promise, generator, array, object, but not the following object was passed: ${String(ret.value)}"`));}
由于本人实力不够,还是坚持继续阅读
第一章
ECMAScript7
js的新标准从提案变成正式总共经历5个阶段
第三章 解构变量
交换
提取
传入函数的参数解构
传入函数参数自带默认值
第四章 字符串的扩展
js允许采用
\uxxx
的形式表示一个字符,其中xxxx表示字符串码点。"\u0061" // "a"
但是这种表示法只限于\u0000 ----\uFFFF之间的字符。超出这个范围的必须用两个字节表示
"\uD842\uDFB7" \"𠮷"
ES6对此进行了改进
"\u{42}\u{43}\u{44}"
JavaScript内部,字符串以UTF-16的形式储存,每个字符固定2个字节,对于那些需要四个字节储存的字符,JavaScript认为他们是占两个字节。
ES6提供codePointAt(0)的方法,能正确处理4个字节的字符,并返回一个字符的码点。
padStart padEnd
ES7推出字符串不全长度功能,如果字符串长度未达到,会自动在头尾补全,
'x'.padStart(5,'ab') // 'ababx';
'x'.padEnd(4,'ab') // 'xaba';
4.10 模板字符串
4.11 实例:模板编译
下面例子,一个通过模板字符串生成真正正式模板的实例
各种奇淫技巧我就不一一详述。
第八章 函数的扩展
写代码经常遇到一个这样的问题,他没有forEach的方法,我们运用扩展符号,轻松将他转为数组。
a.name即返回函数名字
构造函数的名字
bind绑定的函数的名字,返回的是 'bound '
8.5 箭头函数(关键)
当返回的是一个对象的时候呢??意想不到的是,报错了,因为函数默认识别{作为一段代码块,而你则把{当作对象的开头,所以这种情况下必须加上小括号。(),同时箭头函数可以配合变量结构一起使用,相当让人愉悦的一段代码。
返回的对象和传入的对象是一样的值,但是对象早已不是之前的对象,用这种写法来写函数式编程应该会非常舒适。
总结一下,箭头函数最主要的效果是简化回调函数,但这需要建立在对函数熟悉的基础上。但是使用过程中要注意以下几点:
call和普通调用不同,call内传入的参数是就算函数内的this,而此处箭头函数,this永远指向函数本身。而如果是普通函数,this指向window,严格模式下,this指向undefined.,不错的es6。他让js变得简单优雅。。。
下面代码,this永远指向函数本身,因为他是箭头函数。
这里定时器内部箭头函数的this同样指向对象本身
this指向的固定化,为什么呢,因为箭头函数内部根本没有this,所以this永远指向对象本身。正因为如此,所以箭头函数同样不能做构造函数。
函数绑定
箭头函数可以用以将this指向函数本身,这大大简便了js绑定,举个例子react官方说的一个绑定例子
react采用
this.handleClick.bind(this)
,这样的绑定函数会返回一个函数,而返回的新函数通过bind绑定的新函数,下面看mdn对于bind的定义。返回的新函数this永远指向,意思就是,bind函数传入的第一个参数,就算新函数的this,无论你怎么调用,都是这个this,这和箭头函数的核心含义是不谋而合的。下面是react官方的第二种写法,省区了bind步骤,就是因为使用了箭头函数。
8.6 函数绑定
箭头函数可以绑定this,大大减少了显示绑定this对象的方法(call,apply,bind),但是es7提出了新的提案,
::
用来绑定8.7 尾调用优化
说的就算高阶函数
js的函数可以说是非常灵活的可以在任何地方被调用,包括if(内部){},关键不在于函数书写形式,关键在于所返回的是函数还是对象还是字符串,或者根本没有return,
func()()()
只要返回的是所需要的东西即可,不管你后面跟了几个括号。尾调用极其不同的地方在于其特殊的调用函数的位置。
具体可以了解相关调用栈(call stack #17 )由于函数尾部是一个新的函数,所以调用它的函数会被先存入调用栈,等待新函数被找到之后,新函数也会被放入调用栈,然后调用栈按照FILO(先入后出)队列原则,依次执行。
上面代码,如果g不是尾调用,函数f就需要保存内部变量m,n,以及g的调用位置,。但是当g被调用之后,函数f就结束了,所以f(x)函数完全可以被删除。
上面说的就是尾调用优化,可以节省部分内存??
尾递归
函数调用自身称之为递归,在尾部调用自身,称之为尾递归,
下面的是递归函数,调用栈最大承受量为11370次,容易发生栈溢出效应。其复杂度为O(n)
但是对于下面这个函数,尾递归由于全程只发生一个调用栈,复杂度为O(1),当然此刻依然是调用栈溢出,因为只是es6对尾递归进行了优化,你需要开启chrome实验室新功能。
第十一章 Proxy和Reflect
proxy 概述
proxy用于修改某些操作的默认行为,等同于在语言层面做一些事,所以这属于元编程。,即对语言进行编程。
上面的代码对一个空对象做了一层拦截层,重定义了读取属性的set和设置set行为。这里暂时先不解释其具体做法。看看运行结果。
12.二进制数组
ArrayBuffer对象,TypedArray,DataView视图,是JavaScript操纵二进制数据的一个接口,
二进制数组由三个对象组成
很多浏览器API用到了二进数组操作二进制数据,下面是其中的几个。
12.1 ArrayBuffer 对象
概述
ArrayBuffer对象代表储存二进制数据的一段内存,他不能直接读/写,只能通过视图来读写。视图的作用是指以指定格式解读二进制数据。
ArrayBuffer也是一个构造函数,可以分配一段可以存放的数据的内存区域。
下面这段代码生成了一段32字节的内存区域,每个字节的默认值都是0,可以看到ArrayBuffer构造函数的参数是所需要的内存大小(单位位字节)。
为了读写这段内存,需要为它指定视图。创建DataView视图。需要提供ArrayBuffer对象实例作为参数
上面代码对一段32字节的内存建立DataView视图,然后以不带符号的8位整数格式读取第16个元素得到0,因为他的所有都是0。
12.2 TypedArray视图
ArrayBuffer对象作为内存区域存放多种类型数据。同一段内存不同数据的不同解读方式,这就叫做视图。ArrayBuffer存在2种视图,一种是TypedArray视图,另一种是DataView视图,前者所有数组成员都是同一个数据类型吗,后者数组成员可以是不同的数据类型。
13.章 set 和map
set作为es6新的一种数据结构,类似于数组,但是他的成员的值是唯一的。没有重复的值。
set的一些方法如下
set.add({})不断添加{},因为{} === {} // false
WeakSet
和set类,但不同之处在于
Map
map结构的目的和基本用法。
插一道面试题。
目前存在3个ajax访问,当url1和url2同时访问某个接口,只有当两个接口同时拿到数据的时候,url3开始执行去拿某个接口的数据。url1,和url2拿数据的速度未知。可能url1更快,也可能url2更快。只有当2个接口的数据都拿到之后才去拿url3的数据。闲话不多说,上代码
14章lterator 和 for循环
遍历器(lterator)就是这样一种接口机制,为各种不同的接口机制提供统一的访问机制。任何数据结构只要有lterator接口,就能遍历循环。
lterator的作用有三种,
lterator的遍历过程是这样的,
每一次调用next方法,都会返回数据结构当前成员的信息。下面定义一个makeIterator函数用来遍历循环
14.3 调用Iterator调用的默认场合
还有菊花函数
function* (){ yield [1,2,3,4,5] }
上面的[]数组内部内容被自动解构,他后面如果跟的是一个可遍历的结构,他会被用于遍历器的接口。
其他场合
14.4 字符串的Iterator接口
字符串本身其实也可以遍历,他也具有遍历接口
14.6 遍历器对象的return()。throw()
Set 和 Map 结构
Set 和 Map结构具有Iterator接口,可以直接使用for...of循环
16 章 Promise
下面then会生成2个promise,先new一个promise,then里面再生成一个新的promise,通过不断的生成一个新的promise,而产生链式调用,这个和jQuery是不谋而合的。
promise.all
多个rpomise一起完成。
在进行下一步。
下面请看async/await,虽然他也只是基于Generator的语法糖,但是配合promise少不了它。
17章 async和异步操作。
异步编程对于js这门语言非常重要。js是单线程,如果没有异步,就会卡死。
es诞生之前,异步编程大概有以下几种方案
异步
所谓异步就算将一段任务分成两段,先执行一段,然后转而执行其他的任务,等好之后,又回过头来重新执行之前的代码。
下面的就算以回调的方式实现异步代码。但是他会先 输出 123,然输出文件内容,这是典型的异步代码,但是async/await绕来绕去,原本js阻塞的同步代码被写成异步,现在async/await有将他们变成同步的 阻塞代码,醉醉醉。同步=>异步=>同步
callback function 回调函数
我个人觉得这种渣翻译非常容易引起误解,所谓回调函数就算把第二段单独写入一个函数中,等到重写执行该函数的时候重新调用,所以callback直译过来应该是重新调用的意思,而不是所谓的回调函数。
promise
回调函数本身并没有问题,问题在于多个回调函数嵌套,假定读取A文件后再读取B文件,代码如下
为了避免多重嵌套,所以出现了异步函数。然而我觉得这个好失败。怪不得TJ大神要转去玩GO,
17.2 Generator 函数
协程
传统的编程语言早已有异步解决方案,(其实是多任务的解决方案)。其中有一种叫做协程(coroutine),意思是多个线程相互协作,完成异步任务。
协程有点像函数,又有点像线程,流程如下:
上面的协程A就算异步任务。因此他分成2段执行。
Generator函数的概念
他会将函数执行权交出去,即暂停执行。需要暂停的地方用yield,
上述代码,调用Generator函数会返回一个内部指针,g,这是生成器函数不同于普通函数的地方,他返回的指针每次调用next都会指向下一个yield,也就是返回一个对象。
Generator可以暂停执行,这是它可以封装异步函数的根本原因。
关于Generator中的 then,他返回的是什么??,async返回的then呢?
关于Promise
Promise.all(),和Promise差不多。
17.3 Thunk 函数
参数的求值策略
传入的是一个函数,那么传入的函数等到传入的一刻才计算。尾递归就是一个例子,但是尾递归存在栈溢出的性能问题。
17.4 co模块
#####基本用法
co模块是TJ发布的一个小工具。用于generator函数自动执行。
co模块可以让你不用编写Generatar函数的执行器。
上面的代码中,Generator函数只要传入co函数就会自动执行。
co函数返回一个Promise对象,因此可以用then方法添加回调函数。
上面的代码中,等到Generator函数执行结束,就会输出一行提示。
####co模块的原理
为什么co模块可以自动执行Generator函数?
前面说过,Generator就是一个异步执行函数的容器。它自动执行需要一种机制,当异步操作有了结果能够自动交回执行权。
co模块其实就是将两种自动执行器(Thunk函数和Promise对象)包装成了一个模块。使用co的前提条件是,Generator函数的yield命令后面只能是Thunk函数或Promise对象。
下面讲一下基于generator函数的自动执行器。这是理解co函数的关键。
####基于Promise对象的自动执行
还是沿用上面的例子。首先把fs模块的readFile方法包装成一个Promise对象。
手动执行的方法其实就算用then方法层层添加回调函数,理解这一点,就能写出自动执行函数,
上面的代码中,只要Generator函数还没执行到最后异步,next函数就调用自身以实现自动执行。
####co模块的源码
co就是上面这个自动执行的扩展,他的源码只有十几行,非常简单。
首先,co函数接受Generator函数作为参数,返回一个Promise对象。
在返回Promise对象中,co先检查参数gen是否为Generator函数。如果是,就执行该函数,得到内部指针对象;如果不是就返回,并将promise对象的状态改为Resolve。
最后最关键的就算next函数
上面代码中,next函数内部的代码一共只有4行命令。
第一行,检查当前是否为Generator函数最后一步,如果是就返回。
第二行,确保每一步的返回值是Promise对象。
第三行,使用then方法为返回值加上回调函数,然后通过onFullfilled函数再次调用next函数。
第四行,在参数不符合要求的情况下,将promise对象状态改为Rejected,从而终止执行,
并发处理异步操作
co支持并发的异步操作,即允许某些操作同时进行,等到他们完成,才进行下一步。这时要把并发的操作都放在数组或者对象里面,跟在yield语句后面。
上面代码允许并发3个somethingAsync异步操作,等到他们全部完成,才能进行下一步。
17.5 async 函数
他就是Generator函数的语法糖
前文有一个Generator函数,一次读取2个文件
其实就只是将*号换成async,将yield换成await的语法糖。
async函数对Generator函数进行了改进,以下4点体现
2.上面代码调用了asyncReadFile函数,然后他就会自动执行,输出结果,完全不想Generator函数需要调用next方法,或者co模块,才能执行。
3.更好的语义。async和await比起yield语义更加清楚。
4.更广的适用性,co模块约定,yield命令后面只能是Thunk函数或者promise对象,而async函数的await后面能是promise对象和原始类型的值,无论数字对象字符串等。
5.返回值Promise。async函数的返回值是Promise对象,这比Generator函数的返回值是Lterator对象方便多了,你完全可以用then方法指定下一步。
进一步说明,async函数完全可以看作由多个异步操作包装成一个Promise对象,而await命令就算内部then语法糖。
async函数的实现
async函数的实现的实现就是把Generator和自动执行函数包在一个函数中。
The text was updated successfully, but these errors were encountered: