当前位置: 首页 > 编程日记 > 正文

avascript中的this与函数讲解

javascript中的this与函数讲解

前言

javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域。并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码,都存放在Window函数内(这是个假设),也就是说javascript中只有函数作用域(前面假设做前提下)。

作用域是什么

作用域是一个盒子,盒子内部的变量只能在当前盒子中使用,作用域盒子是可以嵌套的,内部盒子的变量对父级盒子是不可见的,因为盒子封闭了他们并且盒子不透明,但是盒子可以看到父级盒子内部定义的变量,因为内部这个盒子与父级的变量同处一个空间,他们是互相看得到的。就像css中的盒模型一样。

以上这个图分为3层作用域,全局作用域、foo函数作用域、bar函数作用域,我们可以清晰的看到三层作用域各自的范围。

this是什么

我们经常用到this,this是代表着什么?this是代表着当前方法执行的环境上下文,那么何为环境上下文,通俗的说,谁调用了函数,谁就是这个函数的环境上下文。例如:

复制代码
function run () {console.log(this)
}var o = {run: run
}run()  //  window对象
o.run  //  o对象
复制代码

在上述代码中,run是一个函数,首先执行run()返回了window对象,为什么呢?我们已经讲过,var定义的变量会默认挂在到window对象中去,那么function定义的函数呢,也会默认挂在到window对象中去,其实我们在执行一个函数如:run() 跟window.run()是一样的,所以,window调用了run,因此函数的this是window。

注意:this的绑定是产生在函数调用时,并非在函数定义时

复制代码
var o = {color: 'red',getColor: function () {console.log(this.color)}
}var color =  'blue'var getColor = o.getColoro.getColor // red
getColor  // blue
复制代码

上述代码,我们将o.getColor方法赋值给了一个变量getColor,然后我们分别执行了两个方法,缺得到了不同的结果,对于o.getColor并没有什么疑问,但是初学者可能认为getColor返回的也应该是red,但事实是blue,这就说明了,this是产生在函数调用时,因为在o.getColor赋值语句,就相当于一下语句

var getColor = function () {console.log(this.color)
}

o.getColor返回的是这个函数,并没有绑定this,也就是说getColor其实是被赋值了一个函数,仅此而已,this是在调用时绑定的,所以得到了那样的结果。

不要被模样给蒙蔽

看下面代码:

复制代码
var o = {run : function () {setTimeout(function () {console.log(this)   }, 1000)}
}
o.run()  //  window对象
复制代码

以上运行了o.run方法,隔一秒输出this,输出了window对象,初学者可能会疑问,o.run调用时明明是在o对象下啊,this应该是o对象啊!不错,有这个疑问说明对this有一定了解了,但是上面案例是在setTimeout方法中的回调函数中输出的this,此回调函数执行时,是以fn()方式执行的(涉及到异步回调),前面说过直接执行函数相当于window.fn,因此输出了window对象。

拓展回调:

回调是进行异步操作常用的功能,上面示例中,我们可以假设为setTimeout是这样定义的

复制代码
function setTimeout (fun) {fun()
}setTimeout (function () {console.log(this)
})
复制代码

可以看出,fun是直接调用的,输出的this必定是window对象。

暴力绑定this

有时候,我们需要强制某个函数中的this为某一对象,我们这时候需要暴力的绑定this,这里,暴力的方法有3个: call、apply、bind。下面通过一个简单的demo来看一下他们的用法。

复制代码
var color = 'blue'var o = {color: 'red',say: function (animal, beautiful) {console.log(this.color + '颜色的' + animal + (beautiful ? '好看': '不好看'))}
}var say= o.saysay('猫', false)   // blue颜色的猫不好看
say.call(o, '猫', true)  // red颜色的猫好看
say.apply(o, ['猫', true])  // red颜色的猫好看
say.bind(o)('猫', true)  // red颜色的猫好看
o.say.call(null, '猫', false)  // blue颜色的猫不好看
复制代码

我们这次将o函数加一个say方法,say方法接收两个参数,第一个数动物,第二个是布尔值代表好不好看,我们还是将o.say赋值给变量say。

say('猫', false) 如期返回了blue颜色

say.call(o, '猫', true),say.apply(o, ['猫', true]),say.bind(o)('猫', true) 这三个都返回了red,可见我们都暴力的绑定了this为o对象。

call和apply的第一个参数都是接收要绑定的对象,也就是告诉引擎:'我要让say方法在o对象的环境下运行,你给我帮顶一下',引擎回答:‘包在我身上’,然后我们就绑定成功了,接下来我们需要传递参数到方法中去,call方法是在第二个参数之后,按顺序的传递参数 到方法中去,apply方法不同,apply方法是在第二个参数以数组的方式将参数传递到方法中去。而bind方法是es5中的方法,用途就在于绑定this指向然后返回已绑定好了的函数,因此,以上三个都输出了red

同样o.say绑定到null或者undefined,引擎会自动绑定到全局对象window下面。

进阶:函数的执行过程

本着菜鸟的思路,努力讲述一下简单的函数执行背后的历程,有错误请指正。

复制代码
function fn (a, b) {var c = 2;function f () {...}
}var o = {}fn.call(o,1,'ok')
复制代码

函数fn执行,会首先产生一个函数活动对象,这个活动对象对外是不可见的,该示例中,fn函数活动对象先绑定了此次调用的this指向o,参数之间的赋值形成arguments对象,然后进行了函数内部的初始化变量,最后执行函数内部的赋值过程。过程如下:

复制代码
function fn (a = 1, b = 'ok') {  var cvar f//活动对象初始化完毕,进行函数体内的其他操作,这根变量提升和函数声明提升有关c = 2f = function () {...}
}
复制代码

总结

总而言之,函数是javascript中最主要的结构,this是javascript甚至每一门高级语言中都需要的动态绑定的指针。能力一般,水平有限,如有错误,轻喷轻骂。

相关文章:

英特尔第11代酷睿处理器TigerLake发布,集成Xe GPU,采用10nm制程技术

2020 年 9 月 2 日,英特尔发布了下一代移动 PC 处理器,,搭载英特尔锐炬 Xe 显卡的全新第 11 代智能英特尔酷睿处理器(代号“Tiger Lake”)是全球性能领先的轻薄型笔记本处理器,能够为Windows 和 ChromeOS 系…

带闰年判断的正则表达式

作者: xixigongzhu(夕夕公主) http://search.csdn.net/Expert/topic/1974/1974227.xml?temp.6640131首先,你的年的范围是1800-3999润年:1800,1900,2100,2200,2300,2500&#x…

FTP命令解析

FTP命令是Internet用户使用最频繁的命令之一,不论是在DOS还是UNIX操作系统下使用FTP,都会遇到大量的FTP内部命令。熟悉并灵活应用FTP的内部命令,可以大大方便使用者,并收到事半功倍之效。 FTP的命令行格式为: ftp -v -…

openresty 前端开发入门五之Mysql篇

2019独角兽企业重金招聘Python工程师标准>>> openresty 前端开发入门五之Mysql篇 这章主要演示怎么通过lua连接mysql,并根据用户输入的name从mysql获取数据,并返回给用户 操作mysql主要用到了lua-resty-mysql库,代码可以在github上…

深入理解JavaScript系列(10):JavaScript核心(晋级高手必读篇)

http://www.cnblogs.com/TomXu/archive/2012/01/12/2308594.html 本篇是ECMA-262-3 in detail系列的一个概述(本人后续会翻译整理这些文章到本系列(第11-19章)。每个章节都有一个更详细的内容链接,你可以继续读一下每个章节对应的…

显示打印对话框

Montaque(Rain ManRainman) http://search.csdn.net/Expert/topic/1756/1756799.xml?temp.8004572加一个printdialog到form上,然后调用 printDialog1.ShowDialog() --------------------------------------------------------------- Dim pt As Printi…

百度CTO王海峰服贸会展示AI新基建成果,飞桨获“科技创新服务示范案例”奖

AI正在为各行各业注入新活力,而AI新基建也在为包括服务贸易领域在内的社会经济发展提供新动力。9月4日,万众瞩目的2020中国国际服务贸易交易会正式召开。这是疫情发生以来,我国在线下举办的第一场重大国际经贸活动,吸引了1.8万家境…

创建画布(验证码)

<?php //创建画布$width 500;$height 800;$imageimagecreatetruecolor($width,$height);//var_dump($image); //处理画布 //imagecolorallocate() 分配颜色到画布上&#xff0c;选择一个颜色。//分配颜色$greenimagecolorallocate($image,0,255,0);//填充&#xff08;油漆…

认知推理下的常识知识库资源、常识测试评估与中文实践项目索引

作者 | 刘焕勇责编 | 李雪敬出品 | CSDN博客Cognitive InferenceCognitive Inference&#xff0c;认知推理、常识知识库、常识推理与常识推理评估的系统项目&#xff0c;以现有国内外已有的常识知识库为研究对象&#xff0c;从常识知识库资源建设和常识推理测试评估两个方面出发…

句号一定要划在句子最美的地方

句号一定要划在句子最美的地方。。。。。。。。。。。。。离职中。。。。转载于:https://blog.51cto.com/luoguoling/944357

调用系统中的默认EMAIL程序

System.Diagnostics.Process.Start("mailto:YourReceiverabcd.com?subjectWhatever&bodyWhatever")

功能点分析:商品类目表

前言作为电商网站&#xff0c;必然要有商品类目表&#xff0c;以便商品分类检索。而设计商品类目表&#xff0c;又是一件特别繁杂的事情。一件商品可能有多个类目来检索出来&#xff0c;比如苹果手机&#xff0c;可以从品牌检索也可以从手机检索。一个类目对应多个商品&#xf…

Iframe 用法浅析

解释成“浏览器中的浏览器“很是恰当 <iframe frameborder0 width170 height100 marginheight0 marginwidth0 scrollingno src"move-ad.htm"></iframe> <IFRAME>用于设置文本或图形的浮动图文框或容器。BORDER<IFRAME BORDER"3">…

MySQL之简单示例

Create Table1.创建数据表 CREATE TABLE amount ( id int(11) NOT NULL AUTO_INCREMENT, amount decimal(10,2) DEFAULT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8DELIMITER $$2.创建触发器示例 &#xff08;1&#xff09;CREATE /*[DEFINER { u…

滴滴AI Labs负责人叶杰平离职!CTO 张博接任

叶杰平9 月 7 日&#xff0c;滴滴出行副总裁、滴滴出行研究院副院长、AI Labs 负责人叶杰平发布内部信&#xff0c;表示即将于近期离职。经滴滴公关部负责人证实&#xff0c;确认叶杰平将离职一事属实。有人猜测&#xff0c;这位 AI 技术大牛的离职&#xff0c;似乎与滴滴近期对…

Alipay秘钥问题

有三种秘钥一个是应用公钥 一个是支付宝公钥 ALIPAY_PUBLIC_KEY 还有一个是秘钥 RSA_PRIVATE_KEY 用支付宝工具生成的那两个分别是 应用公钥 和 秘钥 应用公钥需要提交到支付宝 代码里要用到的两个秘钥分别是 支付宝公钥 和 秘钥 弄了半天总算通了...转载于:https://www…

各种媒体在线播放代码

<embed src"http://wmt2.aboutmedia.com.tw/Aboutmedia/warner/mtv/naying-021011_01v_120k.wmv";; autostart"true" loop"true" width"200" height"150" > 把这个网址http://wmt2.aboutmedia.com.tw/Aboutmedia/wa…

网友:Java岗,自学一个月跳槽计算机视觉!附学习资源合集

笔者在脉脉上看到一条帖子&#xff1a;原来Java岗&#xff0c;自学一个月成功跳槽视觉算法岗。这已经不是笔者第一次看到转行成功的程序员案例了&#xff0c;而大家的跳槽动机基本上都离不开&#xff0c;发展趋势、岗位高薪、职业兴趣。计算机视觉行业真相&#xff1a;竞争压力…

Github的Tom大鸟:我是如何拒绝微软30w的诱惑,专注于Github事业

08是闰年&#xff0c;嗯&#xff0c;这年有366天&#xff08;废话真多&#xff09;&#xff0c;大概就在去年的此时此刻&#xff0c;我自己一个人孤伶伶坐在旧金山的某个叫Zeke的球迷酒吧。通常我不会去球迷吧鬼混的&#xff0c;更不会来SOMA这个鸟地方&#xff08;SOMA是旧金山…

Oracle数据库文件坏块损坏的恢复方法

故障描述打开oracle数据库报错 “system01.dbf需要更多的恢复来保持一致性&#xff0c;数据库无法打开”。经检测数据库文件发现sysaux01.dbf有坏块&#xff0c;sysaux01.dbf文件损坏。数据库没有备份&#xff0c;不能通过备份去恢复数据库。现急需恢复zxfg用户下的数据。故障分…

“画中画”效果--谈IFRAME标签的使用

作者&#xff1a;秋实 文章来源&#xff1a;天极网页陶吧 纵观时下网站&#xff0c;本来网速就有些慢&#xff0c;可是几乎每页都要放什么Banner&#xff0c;栏目图片&#xff0c;版权等一大堆雷同的东西&#xff0c;当然&#xff0c;出于网站风格统一、广告效应的需要&…

Cognitive Inference:认知推理下的常识知识库资源、常识推理测试评估与中文实践项目索引...

作者 | 刘焕勇责编 | 李雪敬出品 | CSDN博客CognitiveInferenceCognitive Inference&#xff0c;认知推理、常识知识库、常识推理与常识推理评估的系统项目&#xff0c;以现有国内外已有的常识知识库为研究对象&#xff0c;从常识知识库资源建设和常识推理测试评估两个方面出发…

敏捷开发实践总结(二):关于测试

用了两个冲刺周期&#xff0c;我们组算是把敏捷开发的测试流程给捋顺了。这里对我们的测试&#xff0c;以及敏捷开发中的测试做一个小结。一、开发组一定不能讳疾忌医。作为开发人员&#xff0c;一定要秉着这个出发点去看待测试。业务测试测试组测试&#xff0c;自测&#xff0…

手机网站的几点注意

http://www.haorooms.com/post/phone_web转载于:https://www.cnblogs.com/momox/p/6252679.html

HEAD元素使用集锦

作者&#xff1a;火焰鸟 文章来源&#xff1a;大众网络报 HTML文档由两部分组成&#xff1a;Head&#xff08;主题部分&#xff0c;一般来说是不可见的&#xff09;和Body&#xff08;正文部分&#xff0c;在浏览器中是可见的&#xff09;。随着FrontPage及Dreamweaver&…

10 个 Python 工程师,9 个不合格!

毋庸置疑&#xff0c;Python越来越被认可为程序员新时代的风口语言。无论是刚入门的程序员&#xff0c;还是年薪百万的 BATJ 的大牛都无可否认&#xff1a;Python的应用能力是成为一名码农大神的必要项。 所以&#xff0c;很多程序员把Python当做第一语言来学习。 但对于Python…

使用谷歌jquery库文件的理由

使用谷歌jquery库文件的理由 最近看到&#xff0c;那些引用jquery的文件那些网站&#xff0c;好多是使用谷歌的库&#xff1b;像这样的<script type”text/javascript”src”http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js“></script>(最近发展…

apache性能测试工具ab使用详解

网站性能压力测试是服务器网站性能调优过程中必不可缺少的一环。只有让服务器处在高压情况下&#xff0c;才能真正体现出软件、硬件等各种设置不当所暴露出的问题。性能测试工具目前最常见的有以下几种&#xff1a;ab、http_load、webbench、siege。今天我们专门来介绍ab。ab是…

HTML-加速、再加速

作者&#xff1a;听风 文章来源&#xff1a;eNet技术学院web开发人员是否必须掌握复杂的组件技术才能加快html页面的访问速度&#xff1f;答案是&#xff1a;不一定&#xff01;实际上&#xff0c;有许多关于HTML与DHTML方面的技巧&#xff0c;它们原理简单而且上手容易。无…

ECCV 2020 | 对损失信息进行建模,实现信号处理高保真还原

编者按&#xff1a;信号在我们的日常生活中随处可见&#xff0c;例如&#xff1a;声音、图像、视频等。然而在信号的传输或存储过程中&#xff0c;往往会面临信号失真、质量变差等问题。今天这篇文章就来探讨一下信号处理中的信息丢失问题&#xff0c;其中包括微软亚洲研究院机…