From e3ef193e5d80b78bb647fb04297448312a5fb381 Mon Sep 17 00:00:00 2001 From: qianguyihao Date: Sat, 17 Mar 2018 22:24:47 +0800 Subject: [PATCH] =?UTF-8?q?add=EF=BC=9A=EF=BC=881=EF=BC=89ES6=E3=80=82?= =?UTF-8?q?=EF=BC=882=EF=BC=89=E5=85=B3=E4=BA=8Ethis=E7=9A=84=E4=B8=80?= =?UTF-8?q?=E9=81=93=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 03-JavaScript(二)/this.md | 76 ++++++++- 03-JavaScript(二)/浅拷贝和深拷贝.md | 24 +++ 10-ES6/02-ES6的常用语法.md | 236 +++++++++++++++++++++++++- README.md | 2 +- 4 files changed, 331 insertions(+), 7 deletions(-) create mode 100644 03-JavaScript(二)/浅拷贝和深拷贝.md diff --git a/03-JavaScript(二)/this.md b/03-JavaScript(二)/this.md index 508d7b4..6ff260d 100644 --- a/03-JavaScript(二)/this.md +++ b/03-JavaScript(二)/this.md @@ -7,23 +7,91 @@ - 特别是当我们不知道一个对象是什么,或者这个对象没有名字但又很想调用它的时候,就会使用到this对象。 -举例: +**举例:** - 遍历DOM对象,绑定click事件,调用当前点击的对象的id,而不是所有对象的id。 +代码: + +```html + + + + + Document + + + + +
+
div0
+
div1
+
div2
+
div3
+
div4
+
+ + + + + +``` + + +上方代码的正确打印结果是5。你可能会觉得很惊讶。我们来解释一下: + +当代码执行完毕后,i已经等于5了。因为一旦运行程序,for循环已经执行完了,此时i等于5。 + +如果我们尝试在 myDiv[i].onclick事件中写代码的时候,如果打印: + +``` + console.log(i); //打印结果为5 +``` + + +如果打印: + +``` + console.log(myDiv[i].id); +``` + +上方这行代码,打印会报错,因为i=5;如果想打印每个div的id,应该这样写: + +``` + console.log(this.id); +``` + +你看,this的作用,就体现出来了。 ### 全局作用域中的this 当一段代码在浏览器中执行时,所有的全局变量和对象都是在window对象上定义的。换而言之,所有的全局变量和对象都属于window对象。 - ### this的定律 - this关键字永远指向函数(方法)运行时的**所有者**。 - ### 函数赋值给变量时,this指向window diff --git a/03-JavaScript(二)/浅拷贝和深拷贝.md b/03-JavaScript(二)/浅拷贝和深拷贝.md new file mode 100644 index 0000000..b6fb101 --- /dev/null +++ b/03-JavaScript(二)/浅拷贝和深拷贝.md @@ -0,0 +1,24 @@ + +## 浅拷贝 + +对于对象或数组类型,当我们将a赋值给b,然后更改b中的属性,a也会随着变化。 + +也就是说,a和b指向了同一块堆内存,所以修改其中任意的值,另一个值都会随之变化,这就是浅拷贝。 + +## 深拷贝 + +那么相应的,如果给b放到新的内存中,将a的各个属性都复制到新内存里,就是深拷贝。 + +也就是说,当b中的属性有变化的时候,a内的属性不会发生变化。 + + + + + +参考链接: + +- [深拷贝与浅拷贝的实现(一)](http://www.alloyteam.com/2017/08/12978/) + +- [javaScript中浅拷贝和深拷贝的实现](https://github.com/wengjq/Blog/issues/3) + + diff --git a/10-ES6/02-ES6的常用语法.md b/10-ES6/02-ES6的常用语法.md index 72bf4b0..21277ef 100644 --- a/10-ES6/02-ES6的常用语法.md +++ b/10-ES6/02-ES6的常用语法.md @@ -1,4 +1,170 @@ +## 前言 + +文本主要内容: + +- Promise(比较重要) + +- Symbol + +- async函数 + +## Promise + +### 概述 + +Promise对象: 代表了未来某个将要发生的事件(通常是一个异步操作)。 + + +ES6中的promise对象, 可以**将异步操作以同步的流程表达出来,**很好地解决了**回调地狱**的问题(避免了层层嵌套的回调函数)。在使用ES5的时候,在多层嵌套回调时,写完的代码层次过多,很难进行维护和二次开发。 + + + +ES6的Promise是一个构造函数, 用来生成promise实例。 + + +### promise对象的3个状态 + +- pending: 初始化状态 + +- fullfilled: 成功状态 + +- rejected: 失败状态 + +### 使用promise的基本步骤 + +(1)创建promise对象 + +(2)调用promise的then() + + +代码格式如下: + +```javascript + let promise = new Promise((resolve, reject) => { + //进来之后,状态为pending + console.log('111'); //这一行代码是同步的 + //开始执行异步操作(这里开始,写异步的代码,比如ajax请求 or 开启定时器) + if (异步的ajax请求成功) { + console.log('333'); + resolve();//如果请求成功了,请写resolve(),此时,promise的状态会被自动修改为fullfilled + } else { + reject();//如果请求失败了,请写reject(),此时,promise的状态会被自动修改为rejected + } + }) + console.log('222'); + + //调用promise的then() + promise.then(() => { + //如果promise的状态为fullfilled,则执行这里的代码 + console.log('成功了'); + } + , () => { + //如果promise的状态为rejected,则执行这里的代码 + console.log('失败了'); + + } + ) +``` + +代码解释: + +(1)当new Promise()执行之后,promise对象的状态会被初始化为`pending`,这个状态是初始化状态。`new Promise()`这行代码,括号里的内容是同步执行的。括号里定义一个function,function有两个参数:resolve和reject。如下: + + +- 如果请求成功了,请写resolve(),此时,promise的状态会被自动修改为fullfilled。 + +- 如果请求失败了,请写reject(),此时,promise的状态会被自动修改为rejected + +(2)promise.then()方法,括号里面有两个参数,分别代表function1和function2: + +- 如果promise的状态为fullfilled,则执行function1里的内容 + +- 如果promise的状态为rejected,则执行function2里的内容 + +另外,resolve()和reject()这两个方法,是可以给promise.then()传递参数的。如下: + + +```javascript + let promise = new Promise((resolve, reject) => { + //进来之后,状态为pending + console.log('111'); //这行代码是同步的 + //开始执行异步操作(这里开始,写异步的代码,比如ajax请求 or 开启定时器) + if (异步的ajax请求成功) { + console.log('333'); + resolve('haha');//如果请求成功了,请写resolve(),此时,promise的状态会被自动修改为fullfilled + } else { + reject('555');//如果请求失败了,请写reject(),此时,promise的状态会被自动修改为rejected + } + }) + console.log('222'); + + //调用promise的then() + promise.then((successMsg) => { + //如果promise的状态为fullfilled,则执行这里的代码 + console.log(successMsg, '成功了'); + } + , (errorMsg) => { + //如果promise的状态为rejected,则执行这里的代码 + console.log(errorMsg, '失败了'); + + } + ) +``` + + + +### ajax请求的举例(涉及到嵌套的回调) + +```javascript + //定义一个请求news的方法 + function getNews(url) { + //创建一个promise对象 + let promise = new Promise((resolve, reject) => { + //初始化promise状态为pending + //启动异步任务 + let request = new XMLHttpRequest(); + request.onreadystatechange = function () { + if (request.readyState === 4) { + if (request.status === 200) { + let news = request.response; + resolve(news); + } else { + reject('请求失败了。。。'); + } + } + }; + request.responseType = 'json';//设置返回的数据类型 + request.open("GET", url);//规定请求的方法,创建链接 + request.send();//发送 + }) + return promise; + } + + getNews('http://localhost:3000/news?id=2') + .then((news) => { + console.log(news); + document.write(JSON.stringify(news)); + console.log('http://localhost:3000' + news.commentsUrl); + return getNews('http://localhost:3000' + news.commentsUrl); + }, (error) => { + alert(error); + }) + .then((comments) => { + console.log(comments); + document.write('




' + JSON.stringify(comments)); + }, (error) => { + alert(error); + }) + +``` + + + + + + + ## Symbol @@ -59,8 +225,34 @@ Symbol是函数,但并不是构造函数。创建一个Symbol数据类型: 20180317_1145.png +现在我们用for in尝试对上面的obj进行遍历: -### 创建Symbol属性值时,传参 +```javascript + let mySymbol = Symbol(); + + let obj = { + name: 'smyhvae', + age: 26 + }; + + obj[mySymbol] = 'hello'; + + console.log(obj); + + //遍历obj + for (let i in obj) { + console.log(i); + } +``` + +打印结果: + +20180317_1817.png + +从打印结果中可以看到:for in、for of 遍历时不会遍历Symbol属性。 + + +### 创建Symbol属性值时,传参作为标识 如果我通过 Symbol()函数创建了两个值,这两个值是不一样的: @@ -73,7 +265,9 @@ Symbol是函数,但并不是构造函数。创建一个Symbol数据类型: console.log(mySymbol2); //打印结果:Symbol() ``` -上面代码中,倒数第三行的打印结果也就表明了,二者的值是不相等的。 +20180317_1733.png + +上面代码中,倒数第三行的打印结果也就表明了,二者的值确实是不相等的。 最后两行的打印结果却发现,二者的打印输出,肉眼看到的却相同。那该怎么区分它们呢? @@ -82,14 +276,52 @@ Symbol是函数,但并不是构造函数。创建一个Symbol数据类型: +```javascript + //在括号里加入参数,来标识不同的Symbol + let mySymbol1 = Symbol('one'); + let mySymbol2 = Symbol('two'); + console.log(mySymbol1 == mySymbol2); //打印结果:false + console.log(mySymbol1); //打印结果:Symbol(one) + console.log(mySymbol2); //打印结果:Symbol(two)。颜色为红色。 + console.log(mySymbol2.toString());//打印结果:Symbol(two)。颜色为黑色。 ``` +打印结果: + +20180317_1739.png + +### 定义常量 + +Symbol 可以用来定义常量: + + + + +```javascript + const MY_NAME = Symbol('my_name'); ``` +### 内置的 Symbol 值 + +除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。 + +- `Symbol.iterator`属性 + +对象的`Symbol.iterator`属性,指向该对象的默认遍历器方法。 + + + +### async函数 + + + + + + diff --git a/README.md b/README.md index 811241a..c45f39c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -前端入门和进阶教程。从零开始学前端,做一个web全栈工程师。持续更新... +前端入门和进阶学习笔记。从零开始学前端,做一个web全栈工程师。持续更新... 更多内容,请点开文件夹。