深入理解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 初体验(建议学习jquery)
Apr 25 Javascript
JavaScript高级程序设计(第3版)学习笔记8 js函数(中)
Oct 11 Javascript
Event altKey,ctrlKey,shiftKey属性解析
Dec 18 Javascript
js的[defer]和[async]属性
Nov 24 Javascript
检测一个函数是否是JavaScript原生函数的小技巧
Mar 13 Javascript
Node.js的项目构建工具Grunt的安装与配置教程
May 12 Javascript
无缝滚动的简单实现代码(推荐)
Jun 07 Javascript
AngularJs bootstrap详解及示例代码
Sep 01 Javascript
微信小程序 仿猫眼实现实例代码
Mar 14 Javascript
详解微信小程序input标签正则初体验
Aug 18 Javascript
Vue.js上传图片到阿里云OSS存储的方法示例
Dec 13 Javascript
vue通过数据过滤实现表格合并
Nov 30 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开发环境配置记录
2011/01/14 PHP
getimagesize获取图片尺寸实例
2014/11/15 PHP
php+mysqli事务控制实现银行转账实例
2015/01/29 PHP
PHP array_reduce()函数的应用解析
2018/10/28 PHP
PHP封装类似thinkphp连贯操作数据库Db类与简单应用示例
2019/05/08 PHP
[JS源码]超长文章自动分页(客户端版)
2007/01/09 Javascript
Flexigrid在IE下不显示数据的有效处理方法
2014/09/04 Javascript
JS制作简单的三级联动
2015/03/18 Javascript
js实现上一页下一页的效果【附代码】
2016/03/10 Javascript
AngularJS 中的指令实践开发指南(一)
2016/03/20 Javascript
JS生成某个范围的随机数【四种情况详解】
2016/04/20 Javascript
JS实现页面数据无限加载
2016/09/13 Javascript
js 实现省市区三级联动菜单效果
2017/02/20 Javascript
微信小程序开发之相册选择和拍照详解及实例代码
2017/02/22 Javascript
Node.js中看JavaScript的引用
2017/04/22 Javascript
javascript代码优化的8点总结
2018/01/29 Javascript
vue-cli扩展多模块打包的示例代码
2018/04/09 Javascript
Vue 框架之键盘事件、健值修饰符、双向数据绑定
2018/11/14 Javascript
Koa日志中间件封装开发详解
2019/03/09 Javascript
基于Vue CSR的微前端实现方案实践
2020/05/27 Javascript
vue实现列表滚动的过渡动画
2020/06/29 Javascript
[46:09]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS VG第三场
2014/05/26 DOTA
Python列表(list)、字典(dict)、字符串(string)基本操作小结
2014/11/28 Python
详解Python核心对象类型字符串
2018/02/11 Python
解决pyinstaller打包发布后的exe文件打开控制台闪退的问题
2019/06/21 Python
python Pillow图像处理方法汇总
2019/10/16 Python
Python多线程Threading、子线程与守护线程实例详解
2020/03/24 Python
KIKO MILANO荷兰网上商店:意大利专业化妆品品牌
2017/05/12 全球购物
印度和世界各地的精美产品:Ikka Dukka
2018/02/12 全球购物
Kate Spade澳大利亚官方网站:美国设计师手袋品牌
2019/09/10 全球购物
优秀党员主要事迹
2014/01/19 职场文书
2015年医院护理部工作总结
2015/04/23 职场文书
检察院起诉书
2015/05/20 职场文书
班主任远程培训研修日志
2015/11/13 职场文书
2016年党员公开承诺书范文
2016/03/24 职场文书
python读取mat文件生成h5文件的实现
2022/07/15 Python