简述this,call,apply,bind之间的关系
一、什么是this?
this是JavaScript语言的一个关键字,它是函数运行时在函数体内部自动生成的一个对象,只能在函数体内部使用。函数的不同使用场合,this的指向不同。
在ES5中,this永远指向最终调用它的对象。
例1: 这里最终调用函数a的对象是全局window,相当于window.a()。 所以this指向window,this.name的值为全局变量name的值 'windowsName'。var name = "windowsName"; function a () {var name = "Cherry";console.log(this.name); // windowsNameconsole.log(this); // [object Window] } a(); console.log(this) // [object Window]
例2: a.fn()调用函数fn的最终对象是a,this指向对象a,所以最终的name值是'skillnull'。 window.a.fn()调用函数fn的最终对象是a,this指向a,所以最终的name值是'skillnull'。 注:由于window下的变量和方法访问和调用的时候可以省略window,所以a.fn() === window.a.fn()。 b()调用函数fn的最终对象是window,this指向window,所以最终的name值是'windowsName'。这里将a.fn赋值给变量b的时候并没有调用fn。 var name = "windowsName"; var a = {name: "skillnull",fn: function () {console.log(this.name);} } a.fn(); // skillnull window.a.fn(); // skillnullvar b = a.fn; b(); // windowsName
二、如何改变this的指向?
- 使用 ES6 的箭头函数
箭头函数的 this 始终指向函数定义时的 this,而非执行时。例3: 注:若setTimeout推迟执行的函数是某个对象的方法,那么该方法中的this关键字将指向全局环境。 由此可以看出a.fn2()中被setTimeout推迟执行的函数的最终调用对象是window,this指向window, 而window中没有fn1方法,所以最终结果为错误信息:this.fn1 is not a function。 a.fn3()中被setTimeout推迟执行的函数使用了箭头函数,此时的this指向函数定义时的this,即a,所以最终结果为:skillnull。 a.fn4()中的函数没有被setTimeout推迟执行,最终对象仍为a,此时的this指向a,所以最终结果为:skillnull。var name = "windowsName"; var a = {name: "skillnull",fn1: function () {console.log(this.name)},fn2: function () {// console.log(this) // asetTimeout(function () {// console.log(this) // [object Window]this.fn1()}, 100);},fn3: function () {setTimeout(() => {// console.log(this) // athis.fn1()}, 100);},fn4: function () {this.fn1()} }; a.fn2() // this.fn1 is not a function a.fn3() // skillnull a.fn4() // skillnull
- 在函数内部使用 that = this
如果上面例子中的fn2中使用that = this改变一下this的指向,此时that属于fn2的内部变量,指向a,所以最终结果为:skillnull fn2: function () {var that = this;setTimeout(function () {// console.log(that) // athat.fn1()}, 100); }
- new 实例化一个对象
如果函数调用前使用了 new 关键字, 则是调用了构造函数。这看起来就像创建了新的函数,但实际上 JavaScript 函数是重新创建的对象。new实例化一个对象的过程如下:
1.创建一个空对象 obj;
2.将新创建的空对象的隐式原型指向其构造函数的显示原型。
3.使用 call 改变 this 的指向
4.如果无返回值或者返回一个非对象值,则将 obj 返回作为新对象;如果返回值是一个新对象的话那么直接直接返回该对象。伪代码表示: var a = new myFunction("Li", "Yafei"); new myFunction {var obj = {};obj.__proto__ = myFunction.prototype;var result = myFunction.call(obj, "Li", "Yafei");return typeof result === 'obj' ? result : obj; }
- 使用 apply、call、bind
例4: call、apply、bind都可以更改this的指向,三者作用相同。 由于a.fn赋值给全局变量b的时候没有执行,上面已经说过,此时的this指向widnow,调用b('skill', 'null')的结果为:i am skillnull 而在调用方法b的时候使用call、apply或bind,将此时的this指向a,所以最终结果是:i am not skillnull
var name = 'i am ' var a = {name: "i am not ",fn: function (a, b) {console.log(this.name + a + b)} }var b = a.fn; b('skill', 'null') // i am skillnull b.call(a, 'skill', 'null') // i am not skillnull b.apply(a, ['skill', 'null']) // i am not skillnull b.bind(a, 'skill', 'null')() // i am not skillnull
三、call、apply、bind 和 this 的关系
从上面的文章可以看出来,其实call、apply、bind最常用的用途是更改this指向。
四、call、apply、bind三者的区别
call和apply不同之处主要在于参数的形式,call参数是一个列表,apply参数是一个数组。
而bind会创建一个新函数,需要手动调用,bind的参数形式和call相同。
注:如果当前函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象)。
转载于:https://www.cnblogs.com/Man-Dream-Necessary/p/9995784.html
简述this,call,apply,bind之间的关系相关推荐
- 简述机器指令与微指令之间的关系_技术动态 | 跨句多元关系抽取
第一部分 概述 关系抽取简介 关系抽取是从自由文本中获取实体间所具有的语义关系.这种语义关系常以三元组 <E1,R,E2> 的形式表达,其中,E1 和E2 表示实体,R 表示实体间所具有的 ...
- 构架、框架、设计模式之间的关系简述
一.软件体系结构和框架的定义 软件体系结构的英文单词是"architecture". Architecture的基本词义是建筑.建筑学.建筑风格. 软件体系结构虽然根植于软件工程, ...
- 简述CPU,内存,硬盘,指令之间的关系
几年前记录在云笔记上的东西,整理过来. 1.基础介绍 CPU:中央处理器(Central Processing Unit),是用来表示计算机内部元件功能的术语,CPU内部由数百万至数亿个晶体管构成. ...
- 通过构建城市来解释HTML,CSS和JavaScript之间的关系
by Kevin Kononenko 凯文·科诺年科(Kevin Kononenko) 通过构建城市来解释HTML,CSS和JavaScript之间的关系 (The relationship betw ...
- android 如何获得activity的view对象,Android的Activity 、 Window 、 View之间的关系
什么是Activity .View . Window? Activity:是Android 四大组件之一, 是存放View对象的容器,也是我们界面的载体,可以用来展示一个界面.它有一个SetConte ...
- WSGI、Flask及Werkzeug三者之间的关系
目录 一.WSGI是什么? 二.Werkzeug是什么 三.Flask的WSGI实现 一.WSGI是什么? WSGI是一套接口规范.一个WSGI程序用以接受客户端请求,传递给应用,再返回服务器的响应给 ...
- 日志信息jar包 slf4j-api、slf4j-log4j12、log4j 之间的关系和使用
slf4j-api.slf4j-log4j12.log4j 之间的关系: 首先系统包含slf4j-api作为日志接入的接口:编译时slf4j-api中public final class Logger ...
- 复习javascript中call,apply,bind的用法
一直很难理解js中的call apply bind,在w3schools,mdn阅读了,也看了很多相关的文章,今天我来写下我理解的call apply bind 首先创建一个函数 function m ...
- React学习:组件之间的关系、参数传递-学习笔记
文章目录 React学习:组件之间的关系.参数传递-学习笔记 父到子传递参数 子-父 父-孙 兄弟组件传参 React学习:组件之间的关系.参数传递-学习笔记 父到子传递参数 <!DOCTYPE ...
- call / apply / bind
对于 call / apply / bind 来说,他们的首要目的是用于改变执行上下文的 this 指针. call / apply 对 call / apply 的使用,一般都如下,用于改变执行环境 ...
最新文章
- 在node.js中,使用基于ORM架构的Sequelize,操作mysql数据库之增删改查
- SIFT 特征检测及匹配
- Nginx配置文件粗解
- [UWP小白日记-14]正则表达式
- QT中个数据类型的转换
- Windows服务二:测试新建的服务、调试Windows服务
- 揭秘神仙高校的课堂!网友跪了:这就是差距啊!
- 前端学习(2137):webpack的介绍和安装
- 爬虫——————爬取中金所,深交所,上交所期权数据
- windos dos命令
- C++---动态内存管理
- QuickBI助你成为分析师-仪表板钻取的实现
- 分布式服务-DUBBOX(五):集成服务生产者
- 准备学习研究一下语音识别 请问有哪些值得推荐的书籍 论文 及开源库?
- Activity、View、Window的理解一篇文章就够了
- 黄聪:基于jQuery+JSON的省市区三级地区联动
- PASCAL VOC2012数据集下载地址
- 计算机操作系统(第3版)课后习题答案(完整版)
- ios 边录音边放_iOS 录音、音频的拼接剪切以及边录边压缩转码
- java的学习--第一章 java基础入门
热门文章
- AspSpider再次开放asp.net2.0 免费空间注册
- 重新认识Java包的命名规则
- IDEA右键新建时没有Java Class选项
- js统计字符串中特定字符出现的个数
- 解决jQuery中dbclick事件触发两次click事件
- 28. 字符串的排列(C++版本)
- java实现【国密SM4】加密解密-CBC模式
- mac搜索不到wifi wtg_如何设置隐藏wifi 防止蹭网隐藏wifi方法【详解】
- mysql 5.1 开启慢查询_mysql开启慢查询
- python123词频统计之哈姆雷特_基于Yarn的Spark环境,统计哈姆雷特词频(1)-阿里云开发者社区...