深入理解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 相关文章推荐
广告显示判断
Aug 31 Javascript
SUN的《AJAX与J2EE》全文译了
Feb 23 Javascript
漂亮的提示信息(带箭头)
Mar 21 Javascript
JavaScript中:表达式和语句的区别[译]
Sep 17 Javascript
jquery对元素拖动排序示例
Jan 16 Javascript
深入分析Javascript事件代理
Jan 30 Javascript
Vue.js一个文件对应一个组件实践
Oct 27 Javascript
Bootstrap实现基于carousel.js框架的轮播图效果
May 02 Javascript
JS中Swiper的使用和轮播图效果
Aug 11 Javascript
JavaScript对象的浅拷贝与深拷贝实例分析
Jul 25 Javascript
利用hasOwnProperty给数组去重的面试题分享
Nov 05 Javascript
小程序实现上下移动切换位置
Sep 23 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-MySQL教程归纳总结
2008/06/07 PHP
PHP实现163邮箱自动发送邮件
2016/03/29 PHP
Yii2下session跨域名共存的解决方案
2017/02/04 PHP
javascript编程起步(第四课)
2007/01/10 Javascript
JavaScript脚本性能的优化方法
2007/02/02 Javascript
jQuery入门问答 整理的几个常见的初学者问题
2010/02/22 Javascript
picChange 图片切换特效的函数代码
2010/05/06 Javascript
Jquery AJAX 用于计算点击率(统计)
2010/06/30 Javascript
JavaScript中的立即执行函数表达式介绍
2015/03/15 Javascript
jquery插件tytabs.jquery.min.js实现渐变TAB选项卡效果
2015/08/25 Javascript
js获取本机操作系统类型的两种方法
2015/12/19 Javascript
jquery中键盘事件小结
2016/02/24 Javascript
利用JS判断鼠标移入元素的方向
2016/12/11 Javascript
JS实现鼠标移上去显示图片或微信二维码
2016/12/14 Javascript
js定时器实例分享
2016/12/20 Javascript
JS中with的替代方法与String中的正则方法详解
2016/12/23 Javascript
js控制文本框禁止输入特殊字符详解
2017/04/07 Javascript
通过nodejs 服务器读取HTML文件渲染到页面的方法
2018/05/17 NodeJs
Vue实现base64编码图片间的切换功能
2019/12/04 Javascript
微信小程序顶部导航栏可滑动并选中放大
2019/12/05 Javascript
基于JavaScript实现简单的轮播图
2021/03/03 Javascript
[50:27]OG vs LGD 2018国际邀请赛淘汰赛BO3 第一场 8.26
2018/08/30 DOTA
python中的闭包用法实例详解
2015/05/05 Python
python并发编程之线程实例解析
2017/12/27 Python
django缓存配置的几种方法详解
2018/07/16 Python
python3 字符串/列表/元组(str/list/tuple)相互转换方法及join()函数的使用
2019/04/03 Python
python异步编程 使用yield from过程解析
2019/09/25 Python
推荐值得学习的12款python-web开发框架
2020/08/10 Python
详解canvas绘图时遇到的跨域问题
2018/03/22 HTML / CSS
白俄罗斯大卖场:21vek.by
2019/07/25 全球购物
Perfume’s Club英国官网:购买香水和护肤品
2019/11/02 全球购物
俄罗斯苹果优质经销商商店:iPort
2020/05/27 全球购物
教师竞聘演讲稿
2014/05/16 职场文书
伏羲庙导游词
2015/02/09 职场文书
2016年“抗战胜利纪念日”71周年校园广播稿
2015/12/18 职场文书
nginx配置虚拟主机的详细步骤
2021/07/21 Servers