深入理解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 相关文章推荐
Javascript模块化编程(三)require.js的用法及功能介绍
Jan 17 Javascript
JS判断不能为空实例代码
Nov 26 Javascript
Jquery遍历节点的方法小集
Jan 22 Javascript
创建、调用JavaScript对象的方法集锦
Dec 24 Javascript
jQuery实现可用于博客的动态滑动菜单
Mar 09 Javascript
深入理解JS正则表达式---分组
Jul 18 Javascript
JavaScript 中 avalon绑定属性总结
Oct 19 Javascript
socket.io与pm2(cluster)集群搭配的解决方案
Jun 02 Javascript
node.js+captchapng+jsonwebtoken实现登录验证示例
Aug 17 Javascript
Vue中使用vux配置代码详解
Sep 16 Javascript
JavaScript进阶(四)原型与原型链用法实例分析
May 09 Javascript
解决vue项目 build之后资源文件找不到的问题
Sep 12 Javascript
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
thinkphp5框架调用其它控制器方法 实现自定义跳转界面功能示例
2019/07/03 PHP
JavaScript-世界上误解最深的语言分析
2007/08/12 Javascript
Ext.FormPanel 提交和 Ext.Ajax.request 异步提交函数的区别
2009/11/12 Javascript
jquery动画3.创建一个带遮罩效果的图片走廊
2012/08/24 Javascript
js读写(删除)Cookie实例详解
2013/04/17 Javascript
javascript获取浏览器类型和版本的方法(js获取浏览器版本)
2014/03/13 Javascript
详解JavaScript中数组的相关知识
2015/07/29 Javascript
JavaScript操作select元素和option的实例代码
2016/01/29 Javascript
javaScript数组迭代方法详解
2016/04/14 Javascript
js实现点击按钮弹出上传文件的窗口
2016/12/23 Javascript
JS判断一个数是否是水仙花数
2017/06/11 Javascript
Angular6 发送手机验证码按钮倒计时效果实现方法
2019/01/08 Javascript
Python 字典(Dictionary)操作详解
2014/03/11 Python
浅谈Python数据类型之间的转换
2016/06/08 Python
详解TensorFlow查看ckpt中变量的几种方法
2018/06/19 Python
python机器人运动范围问题的解答
2019/04/29 Python
python binascii 进制转换实例
2019/06/12 Python
tensorflow实现打印ckpt模型保存下的变量名称及变量值
2020/01/04 Python
详解pandas绘制矩阵散点图(scatter_matrix)的方法
2020/04/23 Python
基于 HTML5 WebGL 实现的医疗物流系统
2019/10/08 HTML / CSS
Lands’ End官网:经典的美国生活方式品牌
2016/08/14 全球购物
求两个数的乘积和商数,该作用由宏定义来实现
2013/03/13 面试题
Java基础类库面试题
2013/09/04 面试题
销售员自我评价怎么写
2013/09/19 职场文书
营销与策划专业毕业生求职信
2013/11/01 职场文书
产品质量承诺范本
2014/03/31 职场文书
乡党政领导班子群众路线教育实践活动个人对照检查材料
2014/09/20 职场文书
2014民事授权委托书范本
2014/09/29 职场文书
走群众路线学习笔记
2014/11/06 职场文书
2014年物业管理工作总结
2014/11/21 职场文书
综合办公室岗位职责
2015/04/11 职场文书
辛德勒的名单观后感
2015/06/03 职场文书
心理健康教育培训研修感言
2015/11/18 职场文书
三十年再续同学情倡议书
2019/11/27 职场文书
python基础之爬虫入门
2021/05/10 Python
利用Matlab绘制各类特殊图形的实例代码
2021/07/16 Python