深入理解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 相关文章推荐
javascript 对象比较实现代码
Apr 27 Javascript
Javascript 面向对象 对象(Object)
May 13 Javascript
jQuery EasyUI API 中文文档 - Panel面板
Sep 30 Javascript
纯js网页画板(Graphics)类简介及实现代码
Dec 24 Javascript
JS中的substring和substr函数的区别说明
May 07 Javascript
javascript写的异步加载js文件函数(支持数组传参)
Jun 07 Javascript
Node.js模块加载详解
Aug 16 Javascript
jQuery插件imgPreviewQs实现上传图片预览
Jan 15 Javascript
layer插件select选中默认值的方法
Aug 14 Javascript
vue富文本框(插入文本、图片、视频)的使用及问题小结
Aug 17 Javascript
layui禁用侧边导航栏点击事件的解决方法
Sep 25 Javascript
js实现图片实时时钟
Jan 15 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 实现多服务器共享 SESSION 数据
2009/08/15 PHP
PHP中数组合并的两种方法及区别介绍
2012/09/14 PHP
PHP判断文件是否存在、是否可读、目录是否存在的代码
2012/10/03 PHP
header导出Excel应用示例
2014/01/24 PHP
PHP实现二维数组去重功能示例
2017/01/12 PHP
PHP连接及操作PostgreSQL数据库的方法详解
2019/01/30 PHP
浅谈php常用的7大框架的优缺点
2020/07/20 PHP
JavaScript实现禁止后退的方法
2006/12/27 Javascript
javascript中的数字与字符串相加实例分析
2011/08/14 Javascript
js 判断图片是否加载完以及实现图片的预下载
2014/08/14 Javascript
js父页面与子页面不同时显示的方法
2014/10/16 Javascript
javascript中定义类的方法汇总
2014/12/28 Javascript
ECMAScript 6即将带给我们新的数组操作方法前瞻
2015/01/06 Javascript
推荐5 个常用的JavaScript调试技巧
2015/01/08 Javascript
JS实用技巧小结(屏蔽错误、div滚动条设置、背景图片位置等)
2016/06/16 Javascript
微信小程序  modal弹框组件详解
2016/10/27 Javascript
jQuery Ajax实现跨域请求
2017/01/21 Javascript
面包屑导航详解
2017/12/07 Javascript
详解VUE自定义组件中用.sync修饰符与v-model的区别
2018/06/26 Javascript
this.$toast() 了解一下?
2019/04/18 Javascript
node.js中对Event Loop事件循环的理解与应用实例分析
2020/02/14 Javascript
TypeScript的安装、使用、自动编译的实现
2020/04/10 Javascript
[48:45]Ti4 循环赛第二日 NEWBEE vs EG
2014/07/11 DOTA
python读取和保存视频文件
2018/04/16 Python
Python递归函数 二分查找算法实现解析
2019/08/12 Python
numpy:找到指定元素的索引示例
2019/11/26 Python
Python通过正则库爬取淘宝商品信息代码实例
2020/03/02 Python
python实现密度聚类(模板代码+sklearn代码)
2020/04/27 Python
网络工程师个人的自我评价范文
2013/10/01 职场文书
群众路线教育实践活动心得体会
2014/03/07 职场文书
学校食品安全实施方案
2014/06/14 职场文书
幼儿园秋季开学寄语
2014/08/02 职场文书
低碳环保演讲稿
2014/08/28 职场文书
公司财务经理岗位职责
2015/04/08 职场文书
教师继续教育反思周记
2015/06/25 职场文书
P站美图推荐——变身女主角特辑
2022/03/20 日漫