深入理解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 相关文章推荐
JQuery扩展插件Validate—4设置错误提示的样式
Sep 05 Javascript
JQuery模板插件 jquery.tmpl 动态ajax扩展
Nov 10 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(一)让静态人物动起来
Jan 23 Javascript
浅析js预加载/延迟加载
Sep 25 Javascript
浅谈Unicode与JavaScript的发展史
Jan 19 Javascript
jquery插件unobtrusive实现片段式加载
Jun 15 Javascript
ionic隐藏tabs的方法
Aug 29 Javascript
jQuery动态移除和添加背景图片的方法详解
Mar 07 Javascript
原生JS实现层叠轮播图
May 17 Javascript
vue基于v-charts封装双向条形图的实现代码
Dec 09 Javascript
深入分析jQuery.one() 函数
Jun 03 jQuery
html5调用摄像头截图功能
Jan 18 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抽象类 介绍
2012/06/13 PHP
ThinkPHP进程计数类Process用法实例详解
2015/09/25 PHP
总结PHP如何获取当前主机、域名、网址、路径、端口和参数等
2016/09/09 PHP
php+redis消息队列实现抢购功能
2018/02/08 PHP
PHP匿名函数(闭包函数)详解
2019/03/22 PHP
thinkphp5.1框架中容器(Container)和门面(Facade)的实现方法分析
2019/08/05 PHP
JAVASCRIPT车架号识别/验证函数代码 汽车车架号验证程序
2012/01/08 Javascript
jquery子元素过滤选择器使用示例
2013/06/24 Javascript
Javascript基础知识盲点总结之函数
2016/05/15 Javascript
JS两种类型的表单提交方法实例分析
2016/11/28 Javascript
js原生之焦点图转换加定时器实例
2016/12/12 Javascript
Bootstrap 轮播(Carousel)插件
2016/12/26 Javascript
JS使用面向对象技术实现的tab选项卡效果示例
2017/02/28 Javascript
利用canvas实现的加载动画效果实例代码
2017/07/05 Javascript
使用异步组件优化Vue应用程序的性能
2019/04/28 Javascript
[02:30]DOTA2放量测试专访海涛:呼吁保护新手玩家
2013/08/26 DOTA
Python实现对比不同字体中的同一字符的显示效果
2015/04/23 Python
python Django框架实现自定义表单提交
2016/03/25 Python
Python 给某个文件名添加时间戳的方法
2018/10/16 Python
python实现dijkstra最短路由算法
2019/01/17 Python
Python利用heapq实现一个优先级队列的方法
2019/02/03 Python
Python处理时间日期坐标轴过程详解
2019/06/25 Python
Django后台管理系统的图文使用教学
2020/01/20 Python
python字符串判断密码强弱
2020/03/18 Python
python模拟斗地主发牌
2020/04/22 Python
css3的transition效果和transfor效果示例介绍
2013/10/30 HTML / CSS
总结html5自定义属性有哪些
2020/04/01 HTML / CSS
三年级科学教学反思
2014/01/29 职场文书
《藤野先生》教学反思
2014/02/19 职场文书
法律顾问服务方案
2014/05/15 职场文书
英语教师自荐信
2014/05/26 职场文书
2015年音乐教学工作总结
2015/07/22 职场文书
html+css实现分层金字塔的实例
2021/06/02 HTML / CSS
php修改word的实例方法
2021/11/17 PHP
Python 如何利用ffmpeg 处理视频素材
2021/11/27 Python
Python如何快速找到多个字典中的公共键(key)
2022/04/29 Python