深入理解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 相关文章推荐
extjs 的权限问题 要求控制的对象是 菜单,按钮,URL
Mar 09 Javascript
Jquery操作下拉框(DropDownList)实现取值赋值
Aug 13 Javascript
基于JavaScript实现动态添加删除表格的行
Feb 01 Javascript
原生JavaScript实现动态省市县三级联动下拉框菜单实例代码
Feb 03 Javascript
Bootstrap创建可折叠的组件
Feb 23 Javascript
JavaScript 节流函数 Throttle 详解
Jul 04 Javascript
AngularJS中的JSONP实例解析
Dec 01 Javascript
vue.js 初体验之Chrome 插件开发实录
May 13 Javascript
JavaScript中Hoisting详解 (变量提升与函数声明提升)
Aug 18 Javascript
如何基于js判断浏览器版本
Feb 20 Javascript
vue-autoui自匹配webapi的UI控件的实现
Mar 20 Javascript
vue 验证两次输入的密码是否一致的方法示例
Sep 29 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
便携利器 — TECSUN PL-365简评
2021/03/02 无线电
php 时间计算问题小结
2009/01/04 PHP
PHP类与对象中的private访问控制的疑问
2012/11/01 PHP
php实现的ping端口函数实例
2014/11/12 PHP
php使用explode()函数将字符串拆分成数组的方法
2015/02/17 PHP
PHP使用ffmpeg给视频增加字幕显示的方法
2015/03/12 PHP
使用XHProf查找PHP性能瓶颈的实例
2017/12/13 PHP
PHP接入支付宝接口失效流程详解
2020/11/10 PHP
ext 同步和异步示例代码
2009/09/18 Javascript
JS getStyle获取最终样式函数代码
2010/04/01 Javascript
JavaScript的strict模式与with关键字介绍
2014/02/08 Javascript
JS组件Bootstrap ContextMenu右键菜单使用方法
2016/04/17 Javascript
Node.js 实现简单的接口服务器的实例代码
2017/05/23 Javascript
jquery拖动改变div大小
2017/07/04 jQuery
JS鼠标滚动分页效果示例
2017/07/05 Javascript
JavaScript+CSS相册特效实例代码
2017/09/07 Javascript
JS伪继承prototype实现方法示例
2018/06/20 Javascript
浅谈一种让小程序支持JSX语法的新思路
2019/06/16 Javascript
微信小程序修改数组长度的问题的解决
2019/12/17 Javascript
node.JS事件机制与events事件模块的使用方法详解
2020/02/06 Javascript
[46:40]VGJ.T vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
Python读取ini文件、操作mysql、发送邮件实例
2015/01/01 Python
分享给Python新手们的几道简单练习题
2017/09/21 Python
[原创]教女朋友学Python(一)运行环境搭建
2017/11/29 Python
详解Ubuntu16.04安装Python3.7及其pip3并切换为默认版本
2019/02/25 Python
django 微信网页授权认证api的步骤详解
2019/07/30 Python
python提取xml里面的链接源码详解
2019/10/15 Python
Python实现隐马尔可夫模型的前向后向算法的示例代码
2019/12/31 Python
Pytorch GPU显存充足却显示out of memory的解决方式
2020/01/13 Python
Python可变对象与不可变对象原理解析
2020/02/25 Python
详解Pandas 处理缺失值指令大全
2020/07/30 Python
Woolworth官网:澳洲第一大超市
2017/06/25 全球购物
《月迹》教学反思
2014/02/19 职场文书
物流管理专业毕业生自荐信
2014/03/04 职场文书
保护环境倡议书300字
2014/05/19 职场文书
企业挂职心得体会
2014/09/10 职场文书