add:(1)ES6。(2)关于this的一道题。
This commit is contained in:
parent
db21f181c5
commit
e3ef193e5d
@ -7,23 +7,91 @@
|
||||
|
||||
- 特别是当我们不知道一个对象是什么,或者这个对象没有名字但又很想调用它的时候,就会使用到this对象。
|
||||
|
||||
举例:
|
||||
**举例:**
|
||||
|
||||
- 遍历DOM对象,绑定click事件,调用当前点击的对象的id,而不是所有对象的id。
|
||||
|
||||
代码:
|
||||
|
||||
```html
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport"
|
||||
<title>Document</title>
|
||||
<style>
|
||||
div {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
window.onload = function () {
|
||||
var myDiv = document.getElementsByTagName('div');
|
||||
for (i = 0; i < myDiv.length; i++) {
|
||||
myDiv[i].onclick = function () {
|
||||
console.log(i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
<section>
|
||||
<div id="div0"> div0</div>
|
||||
<div id="div0"> div1</div>
|
||||
<div id="div0"> div2</div>
|
||||
<div id="div0"> div3</div>
|
||||
<div id="div0"> div4</div>
|
||||
</section>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
```
|
||||
|
||||
|
||||
上方代码的正确打印结果是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
|
||||
|
||||
|
||||
|
24
03-JavaScript(二)/浅拷贝和深拷贝.md
Normal file
24
03-JavaScript(二)/浅拷贝和深拷贝.md
Normal file
@ -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)
|
||||
|
||||
|
@ -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('<br><br><br><br><br>' + 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函数
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user