深入理解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组件的一些写法
Sep 10 Javascript
JQuery实现用户名无刷新验证的小例子
Mar 22 Javascript
Javascript 颜色渐变效果的实现代码
Oct 01 Javascript
原始XMLHttpRequest方法详情回顾
Nov 28 Javascript
js QQ客服悬浮效果实现代码
Dec 12 Javascript
jquery获取当前元素索引值用法实例
Jun 10 Javascript
解决vue项目报错webpackJsonp is not defined问题
Mar 14 Javascript
微信小程序左滑删除实现代码实例
Sep 16 Javascript
JS中==、===你分清楚了吗
Mar 04 Javascript
vue tab滚动到一定高度,固定在顶部,点击tab切换不同的内容操作
Jul 22 Javascript
Element Steps步骤条的使用方法
Jul 26 Javascript
解决新建一个vue项目过程中遇到的问题
Oct 22 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实现用户认证及管理完全源码
2007/03/11 PHP
破解.net程序(dll文件)编译和反编译方法
2013/01/31 PHP
Linux系统下使用XHProf和XHGui分析PHP运行性能
2015/12/08 PHP
javascript让setInteval里的函数参数中的this指向特定的对象
2010/01/31 Javascript
在js中判断checkboxlist(.net控件客户端id)是否有选中
2013/04/11 Javascript
extjs表格文本启用选择复制功能具体实现
2013/10/11 Javascript
jQuery插件开发汇总
2016/05/15 Javascript
修改jquery中dialog的title属性方法(推荐)
2016/08/26 Javascript
Bootstrap Search Suggest使用例子
2016/12/21 Javascript
JS简单获取当前日期时间的方法(如:2017-03-29 11:41:10 星期四)
2017/03/29 Javascript
利用forever和pm2部署node.js项目过程
2017/05/10 Javascript
微信小程序实现留言功能
2018/10/31 Javascript
Vue+Node实现商品列表的分页、排序、筛选,添加购物车功能详解
2019/12/07 Javascript
Taro UI框架开发小程序实现左滑喜欢右滑不喜欢效果的示例代码
2020/05/18 Javascript
Element InputNumber计数器的使用方法
2020/07/27 Javascript
跟老齐学Python之折腾一下目录
2014/10/24 Python
Python pickle模块用法实例
2015/04/14 Python
Python中SOAP项目的介绍及其在web开发中的应用
2015/04/14 Python
Python和Perl绘制中国北京跑步地图的方法
2016/03/03 Python
Python实现基本线性数据结构
2016/08/22 Python
pip安装Python库时遇到的问题及解决方法
2017/11/23 Python
Python实现合并两个列表的方法分析
2018/05/28 Python
Pycharm代码无法复制,无法选中删除,无法编辑的解决方法
2018/10/22 Python
jupyter notebook 使用过程中python莫名崩溃的原因及解决方式
2020/04/10 Python
keras 自定义loss层+接受输入实例
2020/06/28 Python
详解Python openpyxl库的基本应用
2021/02/26 Python
HTML5实现多张图片上传功能
2016/03/11 HTML / CSS
幼儿园元旦家长感言
2014/02/27 职场文书
公路绿化方案
2014/05/12 职场文书
学校火灾防控方案
2014/06/09 职场文书
个人学习群众路线心得体会
2014/11/05 职场文书
放弃遗产继承公证书
2015/01/26 职场文书
死亡诗社观后感
2015/06/05 职场文书
龙猫观后感
2015/06/09 职场文书
Nginx性能优化之Gzip压缩设置详解(最大程度提高页面打开速度)
2022/02/12 Servers
Python中的协程(Coroutine)操作模块(greenlet、gevent)
2022/05/30 Python