1,this指向

概念:this是运行环境下的一个系统变量,由于this在不同的执行环境下有不同的值,所以在使用this时,多加注意(使用this之前,先打印)

1.1 在全局作用域下,this默认指向window(前端运行环境),(后端运行环境是空对象{})

<script>console.log(1, this);//window+文件路径
</script>

1.2 在事件函数中,this指向绑定事件的目标

<body><button id="btn2">点我2</button><script>btn2.onclick = function(){console.log(2, this);//<button id="btn2">点我2</button>}</script>
</body>

1.3 在对象中,this指向它所在的对象本身

<script>var zhangsan = {name: "张三",age: 20,eat: function() {console.log(3, this);//{name:"张三",age:20,eat: function() {}}}}zhangsan.eat()
</script>

1.4 在构造函数中,this指向构造函数创建的对象

        function People(name, age) {this.name = name;this.age = age;this.eat = function() {console.log(4, this);//{name:"李四",age:20,eat: function() {}}//{name:"小明",age:30,eat: function() {}}}}var lisi = new People("李四", 20)var xiaoming = new People("小明", 30)lisi.eat();xiaoming.eat();

1.5 在函数嵌套时,内层的函数this不会继承外层函数this的值,会被还原成window

如果内层的函数this不会继承外层函数this的值,内层函数使用箭头函数才能让内层函数的this和外层函数this统一指向

<body><button id="btn5">点我5</button>
</body>
<script>
btn5.onclick = function() {console.log(5.1, this)// <button id="btn5">点我5</button>// 内层函数直接调用function fun() {console.log(5.2, this)//window}fun()// 内层函数用计时器调用setTimeout(function() {console.log(5.3, this)//window}, 100)// 6, 在函数嵌套时, 如果像让内层函数的this和外层函数this统一指向, 内层函数请使用箭头函数console.log(6.1, this)// <button id="btn5">点我5</button>var fun = () => {console.log(6.2, this)// <button id="btn5">点我5</button>}fun()setTimeout(() => {console.log(6.3, this)// <button id="btn5">点我5</button>}, 100)}
</script>

1.6 在函数嵌套时,如果想让内层函数的this和外层函数this统一指向,内层函数请使用箭头函数

1.7 在ajax回调函数中,this指向window

        fetch("https://m.douyu.com/api/room/list?page=1").then(function() {console.log(7, this)//window})

1.8 this指向的修改

  • call(),用函数直接调用call(),第一个参数是this修改后的指向(支持引用类型,如果传入值类型会自动装箱),后边的参数是函数的原始参数,调用call时会直接执行函数
  • apply(),用函数直接调用apply(),第一个参数是this修改后的指向(支持引用类型,如果传入值类型会自动装箱),后边的参数是函数的原始参数所在的数组,调用apply时会直接执行函数
  • bind(),用函数直接调用bind(),第一个参数是this修改后的指向(支持引用类型,如果传入值类型会自动装箱),后边的参数是函数的原始参数,调用bind时不会直接执行函数
        function add(a, b) {console.log(8, this, a + b)}add(3, 4)add.call("李四", 5, 6)//8,{"李四"},11add.apply(false, [5, 6])//8,Boolean{false},11var obj = {name: "思聪",age: 10}// 调用bind后会返回一个新的函数var newAdd = add.bind(obj, 5, 6)// 调用新的函数得到修改后的thisnewAdd()//8,{name:"思聪",age:10}

总结:

1,this指向的几种情况(谁调用,this就指向谁)

  • 默认情况下,this指向window
  • 事件函数中,this指向事件绑定目标
  • 对象中,this指向对象本身
  • 构造函数中,this指向构造函数创建的对象
  • 嵌套函数中,内层函数默认指向window
  • 嵌套函数中,内层见图函数指向外层函数this

2,call,apply,bind 修改this的异同点

  • call和apply 修改this指向时会立即调用函数,bind修改指向不会立即调用函数,会返回一个新函数
  • call和bind的第二个参数时函数的原始参数写法,apply的第二个参数必须事数组,数组中放的是原始参数

3,call,apply和bind的使用场景

  • call适合在调用函数时修改this指向,直接使用call或apply修改即可
  • bind适合在修改this指向时,不立即调用函数,而是时机成熟时在调用的情况,如:计时器,ajax请求等异步回掉函数的修改

2,Promise

2.1 Promise语法

Promise时ES6新增的一个类,可以解决异步操作上的弊端和问题

  • 新建一个Promise对象,参数是回调函数,回调函数有两个参数,这两个参数分别是resolve,reject,这两个参数也是两个函数
  • 如果在peomise对象中开始一个异步操作,如果异步任务出错,就执行reject函数,传入错误信息;如果异步任务成功,就执行resolve函数,传入成功的数据
  • 用promise对象调用then方法,传入成功的回调函数,对应resolve;传入失败的回调函数,对应reject
  • then方法获取成功回调函数的值和失败回调函数的值,也可以使用下边的链式调用结构,因为then的返回值依然是这个promise对象
  • then函数可以直接传入两个回调函数,一个成功函数,一个失败函数,失败函数是可选的。也就是说,如果异步操作成功的话就执行then函数的第一个成功函数,如果不成功的话就执行then函数的第二个失败函数
var promise = new Promise(function(resolve, reject){// resolve 和 reject 也是两个函数, // 在promise对象中开始一个异步操作fs.readFile("./1, es6简介.txt", function(err,data){// 如果异步任务出错,就执行reject函数,传入错误信息if(err)  reject(err.message);// 如果异步任务成功, 就执行resolve函数, 传入成功的数据else resolve(data)})
})
promise.then(function(res){console.log(6, res)
})
promise.catch(function(err){console.log(6, err)
})
var promise = new Promise(function(resolve, reject) {fs.readFile("./data/b.txt", function(err, data) {if (err) reject(err.message)else resolve(data.toString())})
})
//此时异步操作是成功的,所以只打印6.1,而6.2并不打印
promise.then(function(res) {console.log(6.1, res);
}, function(err) {console.log(6.2, err);
})

注意:

  • 成功的回调函数resolve是必选的,必须在then中传入,失败的回调函数reject是可选的,可以省略
  • then函数获取promise异步结果不管在任何事件,任何位置调用,不管调用多少次,总能拿到异步结果

2.2 Promise用法

promise解决异步操作多层嵌套问题,还能解决多异步任务并发执行的问题

2.2.1 解决异步操作多层嵌套问题

创建一个data文件夹里边有四个txt文件,分别是a.txt,b.txt,c.txt,d.txt,内容分别是:床前明月光,疑是地上霜,举头望明月,低头思故乡

var fs = require("fs");// 需求:读取data目录下的4各为念中的4句诗,并按顺序拼接
// 方案三:使用promise解决异步操作多层嵌套问题
new Promise(function(resolve, reject) {fs.readFile("./data/a.txt", function(err, data1) {resolve(data1)})}).then(function(data1) {return new Promise(function(resolve, reject) {fs.readFile("./data/b.txt", function(err, data2) {resolve(data1 + data2)})})}).then(function(data12) {return new Promise(function(resolve, reject) {fs.readFile("./data/c.txt", function(err, data3) {resolve(data12 + data3)})})}).then(function(data123) {return new Promise(function(resolve, reject) {fs.readFile("./data/d.txt", function(err, data4) {resolve(data123 + data4)})})}).then(function(data1234) {console.log(data1234);//床前明月光疑是地上霜举头望明月丢思故乡})// 缺点:promise虽然解决了多任务嵌套问题,但是以上三种方案存在一个共性弊端,就是多异步任务并发执行的问题
2.2.2 解决多异步任务并发执行问题

promise中的异步操作是在new创建直接开始执行的,then函数只是读取异步结果,而不是开始执行异步请求。

// 方案四: 使用promise解决多异步任务并发执行问题
var p1 = new Promise(function(resolve){fs.readFile("./data/a.txt",function(err,data){resolve(data)})
})
var p2 = new Promise(function(resolve){fs.readFile("./data/b.txt",function(err,data){resolve(data)})
})
var p3 = new Promise(function(resolve){fs.readFile("./data/c.txt",function(err,data){resolve(data)})
})
var p4 = new Promise(function(resolve){fs.readFile("./data/d.txt",function(err,data){resolve(data)})
})
//想把多个promise对象合成一个,promise类中提供了两个类方法:all、race
var mergeP = Promise.all([p1,p2,p3,p4])
mergeP.then(function(dataArr){console.log(4, dataArr.join(""))
})
2.2.3 把多个promise对象合成一个的方法:all、race
  • all()参数是数组,数组中放多个promise实例,返回一个新的promise对象,使用合并后的对象调用then获取所有promise的结果,是一个数组,数组中数据顺序和all参数顺序保持一致(注意不是按照执行结束的信后顺序排列)
  • all:党合并的所有promise全部完成之后,才会执行then回调,拿到所有结果
  • race:任意一个合并的promise完成之后,立即调用then回调,只能拿到这一个结果
var p1 = new Promise(function(resolve) {fs.readFile("./data/a.txt", function(err, data) {resolve(data)})
})
var p2 = new Promise(function(resolve) {fs.readFile("./data/b.txt", function(err, data) {resolve(data)})
})
var p3 = new Promise(function(resolve) {fs.readFile("./data/c.txt", function(err, data) {resolve(data)})
})
var p4 = new Promise(function(resolve) {fs.readFile("./data/d.txt", function(err, data) {resolve(data)})
})
Promise.all([p1, p2, p3, p4]).then(function(res) {console.log(2, res.toString());//2,床前明月光,...低头思故乡
})
Promise.race([p1, p2, p3, p4]).then(function(data) {console.log(3, data.toString());//3,低头思故乡
})

补充:类方法、实例方法

  • 类方法:使用类名直接调用的方法 如:Promise.all() Promise.race()
  • 实例方法:创建出来的对象调用的方法 如:p1.then(), p1.catch()

promise语法与用法、this指向和this指向修改相关推荐

  1. Promise的基本用法以及作用

    目录 1- 初识Promise 2- 回调地狱的引发 3- Promise (承诺)的用法 4- async 异步 5- await 6- 使用 async 解决回调地狱问题 1- 初识Promise ...

  2. 装饰器的定义、语法糖用法及示例代码

    1. 装饰器的定义 就是给已有函数增加额外功能的函数,它本质上就是一个闭包函数. 装饰器的功能特点: 不修改已有函数的源代码 不修改已有函数的调用方式 给已有函数增加额外的功能 2. 装饰器的示例代码 ...

  3. C++ I/O语法及其用法

    C++ I/O语法及其用法 构造器 bad clear close eof fail fill flags flush gcount get getline good ignore open peek ...

  4. Promise:Promise.all、Promise.race、Promise.any的用法及区别

    在项目开发过程中经常需要通过异步编程来实现功能,此时就需要我们了解Promise. Promise Promise 是异步编程的一种解决方案,比传统的解决方案回调函数和事件更合理和更强大. 有了Pro ...

  5. es6 Promise 的基本用法

    Promise 的基本用法 ES6 规定,Promise对象是一个构造函数,用来生成Promise实例. 下面代码创造了一个Promise实例. const promise = new Promise ...

  6. Promise语法处理回调地狱

    一.什么是回调地狱 setTimeout(function () { //第一层console.log(111);setTimeout(function () { //第二程console.log(2 ...

  7. 手写promise原理系列七:封装Promise.reject方法,Promise.reject的用法

    在上篇文章中我们知道了 Promise.resolve 的用法以及手动封装了 Promise.resolve 方法,这篇文章继续研究 Promise.reject 方法的用法以及手动封装一个 Prom ...

  8. windows 7编辑启动菜单 bcdedit linux,bcdedit用法详解 windows7/vista启动修改

    bcdedit用法详解 windows7/vista启动修改 (2010-09-11 19:27:28) 标签: 杂谈 bcdedit用法详解 在Vista/2008下,我们通过msconfig的&q ...

  9. JAVAscript中的this指向和this指向的修改

    JAVAscript中的this指向和this指向的修改 this 关键字 一般在函数中使用,表示哪个对象执行了当前函数. 每一个函数内部都有一个关键字是 this . 函数内部的 this 只和函数 ...

  10. 关于指针指向地址中“指向”二字的理解

    为什么要写这文章? 因为对于这个问题:"定义int* p; 系统会给p分配内存空间吗?" 绝大部分回答都是不会. 但是问题来了,刷网课的时候,看到会为p在栈上开辟内存空间. 由此, ...

最新文章

  1. python -m参数
  2. python读取dat数据anaconda_基于python的大数据分析-pandas数据读取(代码实战)
  3. JUnit 测试含有控制台输入的方法
  4. 【PP】长交期计划(LTP)简介
  5. JMeter场景设置叙述
  6. oracle select 行数据_【赵强老师】什么是Oracle的数据字典?
  7. File类、递归、字节流
  8. 2011考研数学概率论基础复习必备知识点
  9. linux安装nginx、php
  10. InstallShield Limited Edition Project 打包windows服务解析
  11. LESS:基础用法学习笔记
  12. 大学数学实验习题--统计推断 (附答案)判断alpha,n与mu,sigma的估计区间长度的关系
  13. 教你怎么从Windows10彻底删除Flash
  14. 服务器gpu芯片排行,GPU云服务器排行榜
  15. 解决win10系统alt+tab切换程序不显示程序缩略图问题
  16. 程序员年后离职跳槽指南
  17. FFmpeg指令(./configure 其他)
  18. java sign函数_C / C ++中是否有标准的符号函数(signum,sgn)?
  19. MySQL用户管理-密码修改-用户授权
  20. openfeign 转发post 接口 错误 Incomplete output stream executing POST http://xxxx

热门文章

  1. OPENCV运动追踪研究和PYTHON及JAVA实现
  2. 虚幻引擎UE4编辑器介绍
  3. 多个excel表合并成一个excel表
  4. 两表联合查询,求TOP100商品。。。。。。。。。。感激不尽!
  5. nginx 基本入门
  6. 网站被挂马的处理办法以及预防措施
  7. android6.0以上模拟位置状态检测
  8. HACCP的相关文献包含哪些?
  9. MySQL设计成一维数据库_mySQL教程 第1章 数据库设计
  10. PythonR LEfSe 分析