深入理解js函数的作用域与this指向


Posted in Javascript onMay 28, 2016

函数的作用域与this指向是js中很重要的一部分,理清这点东西需要个逻辑,看看我的逻辑怎么样...

下面是个提纲,可以直接挑你感兴趣的条目阅读。

• 函数的定义方式:直接定义(window下,内部定义),对象的方法,对象原型的方法;

• 函数的调用方式:直接调用,call/apply,with

• 对于直接定义的函数和对象的方法,作用域默认状态下是它的定义处的作用域链。

• 对于直接定义的函数,this指向window。

• 对于对象的方法,this指向实例化对象(对应于实例化对象默认返回this的情况)。

• 用call/apply改变方法的this指向

• 在函数或方法的定义时可以通过with改变其作用域链。

下面分开来具体说说:

函数的定义,如提纲中提到的可以分为两种:直接定义(window下,内部定义),对象的方法(或对象原型的方法)。从下面的示例代码中可以看到函数fn1与fn2以及对象的方法doFunction在函数使用name时name的值来自相应的域。

 

var name = 'window下的name<br/>';
var resultCon;
function fn1() {
  resultCon.innerHTML += name;
}

function MyObj() {
  var name = 'MyObj下的name<br/>';
  this.doFunction = function() {
    resultCon.innerHTML += name;

在使用name的值时将“name”用“this.name”来代替会出现什么情况呢,看下例:

var name = 'window下的name<br/>';
var resultCon;
function fn1() {
  resultCon.innerHTML += this.name;
}

function MyObj() {
  var name = 'MyObj下的name<br/>';
  this.doFunction = function() {
    resultCon.innerHTML += this.name;

从结果来看可以验证提纲中的第4和5条,也可以看到this和作用域是两套分离的链,遵循个自的变量查询逻辑,具体的查询逻辑在下面的性能分析中会提到,如果是新手建议先看一下“js的作用域链”方面的基础知识。

 关于函数的调用方法,我用下面的方示例说明提纲中的第2、6条:

var name = 'window下的name<br/>';
var resultCon;
function fn1() {
  resultCon.innerHTML += this.name;
}

function MyObj() {
  var name = 'MyObj下的name<br/>';
  this.doFunction = function() {
    resultCon.innerHTML += this.name;

调用时call和apply的使用是为了改变被调用函数的this指向。with的使用是为了改变被调用函数中变量的查询域。我们把上例中的call和name前的this去掉再加上with来演示with的作用。

var name = 'window下的name<br/>';
var resultCon;
function fn1(myScope) {
  with (myScope) {
    resultCon.innerHTML += name;
  }
}

function MyObj(myScope) {
  var name = 'MyObj下的name<br/>';

看到with的使用并不方便,需要在被调用函数中添加with,有人可能想能不能向下面那样调用来整体改变变量作用域而不去改变被调用函数呢?

with (myScope) {
  fn1();
  fn2();
  var obj = new MyObj();
  obj.doFunction();
}

很遗憾,不可以!所以在一些成熟的框架中随处可见call和apply的使用,却很少用到with,在用JSHint检测js语法的时候with处都标了小红点,在一些js编码指导中也建议尽量少用with,因为with改变了变量的默认查询链,所以会给后期的维护人员一些困惑,还有性能方面的一些考虑,请慎用with。

以上这篇深入理解js函数的作用域与this指向就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js创建对象的几种常用方式小结(推荐)
Oct 24 Javascript
JavaScript高级程序设计(第3版)学习笔记9 js函数(下)
Oct 11 Javascript
js 获取input点选按钮的值的方法
Apr 14 Javascript
js实现点击添加一个input节点
Dec 05 Javascript
jQuery的load()方法及其回调函数用法实例
Mar 25 Javascript
解决bootstrap中使用modal加载kindeditor时弹出层文本框不能输入的问题
Jun 05 Javascript
VUE axios上传图片到七牛的实例代码
Jul 28 Javascript
JS使用tofixed与round处理数据四舍五入的区别
Oct 25 Javascript
vue 实现边输入边搜索功能的实例讲解
Sep 16 Javascript
详解VUE单页应用骨架屏方案
Jan 17 Javascript
nuxt 页面路由配置,主页轮播组件开发操作
Nov 05 Javascript
vue使用wavesurfer.js解决音频可视化播放问题
Apr 04 Vue.js
js和C# 时间日期格式转换的简单实例
May 28 #Javascript
JS函数arguments数组获得实际传参数个数的实现方法
May 28 #Javascript
深入理解JS函数的参数(arguments)的使用
May 28 #Javascript
深入理解js中this的用法
May 28 #Javascript
关于function类中定义变量this的简单说明
May 28 #Javascript
Highcharts 多个Y轴动态刷新数据的实现代码
May 28 #Javascript
动态更新highcharts数据的实现方法
May 28 #Javascript
You might like
支持数组的ADDSLASHES的php函数
2010/02/16 PHP
PHP获取文件后缀名的三个函数
2012/10/15 PHP
有关于PHP中常见数据类型的汇总分享
2014/01/06 PHP
php计算两个文件相对路径的方法
2015/03/14 PHP
CodeIgniter开发实现支付宝接口调用的方法示例
2016/11/14 PHP
详谈配置phpstorm完美支持Codeigniter(CI)代码自动完成(代码提示)
2017/04/07 PHP
在Laravel中使用DataTables插件的方法
2018/05/29 PHP
javascript下有关dom以及xml节点访问兼容问题
2007/11/26 Javascript
Jquery作者John Resig自己封装的javascript 常用函数
2009/11/09 Javascript
node.js抓取并分析网页内容有无特殊内容的js文件
2015/11/17 Javascript
angular2使用简单介绍
2016/03/01 Javascript
jQuery弹出层后禁用底部滚动条(移动端关闭回到原位置)
2016/08/29 Javascript
很棒的vue弹窗组件
2017/05/24 Javascript
JavaScript正则表达式函数总结(常用)
2018/02/22 Javascript
Node.js利用console输出日志文件的方法示例
2018/04/27 Javascript
webpack之引入图片的实现及问题
2018/10/08 Javascript
React中this丢失的四种解决方法
2019/03/12 Javascript
微信小程序wx.request拦截器使用详解
2019/07/09 Javascript
vue实现axios图片上传功能
2019/08/20 Javascript
使用xampp将angular项目运行在web服务器的教程
2019/09/16 Javascript
vuejs+element UI table表格中实现禁用部分复选框的方法
2019/09/20 Javascript
Bootstrap告警框(alert)实现弹出效果和短暂显示后上浮消失的示例代码
2020/08/27 Javascript
[01:00:06]加油DOTA_EP01_网络版
2014/08/09 DOTA
Python命令行参数解析模块getopt使用实例
2015/04/13 Python
Python中的推导式使用详解
2015/06/03 Python
Python正则捕获操作示例
2017/08/19 Python
python字符串和常用数据结构知识总结
2019/05/21 Python
Django框架自定义session处理操作示例
2019/05/27 Python
Python实现图片识别加翻译功能
2019/12/26 Python
python中spy++的使用超详细教程
2021/01/29 Python
HTML5的标签的代码的简单介绍 HTML5标签的简介
2012/05/28 HTML / CSS
Lentiamo丹麦:购买便宜的隐形眼镜
2021/01/13 全球购物
《放飞蜻蜓》教学反思
2014/04/27 职场文书
企业文化标语大全
2014/06/10 职场文书
公务员政审材料
2014/12/23 职场文书
详解MongoDB排序时内存大小限制与创建索引的注意事项
2022/05/06 MongoDB