深入理解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单向链表的具体实现实例
Jun 21 Javascript
Javascript 实现的数独解题算法网页实例
Oct 15 Javascript
JS动态添加与删除select中的Option对象(示例代码)
Dec 25 Javascript
javascript中bind函数的作用实例介绍
Sep 28 Javascript
2种jQuery 实现刮刮卡效果
Feb 01 Javascript
jQuery实现预加载图片的方法
Mar 17 Javascript
kindeditor编辑器点中图片滚动条往上顶的bug
Jul 05 Javascript
WordPress中利用AJAX技术进行评论提交的实现示例
Jan 12 Javascript
Bootstrap输入框组件简单实现代码
Mar 06 Javascript
教你完全理解ReentrantLock重入锁
Jun 03 Javascript
vue瀑布流组件实现上拉加载更多
Mar 10 Javascript
如何利用node转发请求详解
Sep 17 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
PHP定时执行计划任务的多种方法小结
2011/12/19 PHP
PHP面向对象的进阶学习(抽像类、接口、final、类常量)
2012/05/07 PHP
探讨PHP JSON中文乱码的解决方法详解
2013/06/06 PHP
jquery的each方法使用示例分享
2014/03/25 Javascript
浅谈jquery回调函数callback的使用
2015/01/30 Javascript
js完美实现@提到好友特效(兼容各大浏览器)
2015/03/16 Javascript
jQuery实现平滑滚动到指定锚点的方法
2015/03/20 Javascript
js控件Kindeditor实现图片自动上传功能
2020/07/20 Javascript
jquery获取input type=text中的值的各种方式(总结)
2016/12/02 Javascript
微信小程序 九宫格实例代码
2017/01/21 Javascript
js导出Excel表格超出26位英文字符的解决方法ES6
2017/11/15 Javascript
Angular5集成eventbus的示例代码
2018/07/19 Javascript
Javascript 类型转换、封闭函数及常见内置对象操作示例
2019/11/15 Javascript
vue离开当前页面触发的函数代码
2020/09/01 Javascript
[04:04]DOTA2亚洲邀请赛比赛场馆&酒店全攻略
2017/03/23 DOTA
一篇不错的Python入门教程
2007/02/08 Python
提升Python程序运行效率的6个方法
2015/03/31 Python
Python中Threading用法详解
2017/12/27 Python
Python iter()函数用法实例分析
2018/03/17 Python
使用python读取txt文件的内容,并删除重复的行数方法
2018/04/18 Python
解决Python获取字典dict中不存在的值时出错问题
2018/10/17 Python
Python 判断奇数偶数的方法
2018/12/20 Python
Pandas读写CSV文件的方法示例
2019/03/27 Python
Python代码实现删除一个list里面重复元素的方法
2019/04/02 Python
使用Python来做一个屏幕录制工具的操作代码
2020/01/18 Python
Django DRF路由与扩展功能的实现
2020/06/03 Python
Python sorted对list和dict排序
2020/06/09 Python
Python json解析库jsonpath原理及使用示例
2020/11/25 Python
Django通过设置CORS解决跨域问题
2020/11/26 Python
Sandro法国官网:法国成衣品牌
2019/08/28 全球购物
小班幼儿评语大全
2014/04/30 职场文书
公开承诺书格式
2014/05/21 职场文书
小学生常见病防治方案
2014/06/06 职场文书
2014年设计师工作总结
2014/11/25 职场文书
英文诗歌翻译方法(赏析)
2019/08/16 职场文书
2022年四月新番
2022/03/15 日漫