深入理解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中暂停功能的实现代码
Mar 04 Javascript
神奇的7个jQuery 3D插件整理
Jan 06 Javascript
使用js实现一个可编辑的select下拉列表
Feb 20 Javascript
AngularJS读取JSON及XML文件的方法示例
May 25 Javascript
jQuery事件对象的属性和方法详解
Sep 09 jQuery
SVG动画vivus.js库使用小结(实例代码)
Sep 14 Javascript
JavaScript解决浮点数计算不准确问题的方法分析
Jul 09 Javascript
你应该了解的JavaScript Array.map()五种用途小结
Nov 14 Javascript
Vue+abp微信扫码登录的实现代码示例
Jan 06 Javascript
JS forEach跳出循环2种实现方法
Jun 24 Javascript
JS canvas实现画板和签字板功能
Feb 23 Javascript
JS中forEach()、map()、every()、some()和filter()的用法
May 11 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
1 Tube Radio
2021/03/02 无线电
其他功能
2006/10/09 PHP
php中显示数组与对象的实现代码
2011/04/18 PHP
[原创]php简单防盗链验证实现方法
2016/07/09 PHP
juqery 学习之五 文档处理 包裹、替换、删除、复制
2011/02/11 Javascript
EXTJS FORM HIDDEN TEXTFIELD 赋值 使用value不好用的问题
2011/04/16 Javascript
Js注册协议倒计时的小例子
2013/06/24 Javascript
jQuery之ajax删除详解
2014/02/27 Javascript
js控制当再次点击按钮时的间隔时间
2014/06/03 Javascript
使用nodejs、Python写的一个简易HTTP静态文件服务器
2014/07/18 NodeJs
JavaScript的History API使搜索引擎抓取AJAX内容
2015/12/07 Javascript
AngularJs动态加载模块和依赖注入详解
2016/01/11 Javascript
JS实现CheckBox复选框全选、不选或全不选功能
2020/07/28 Javascript
javascript事件处理模型实例说明
2016/05/31 Javascript
jQuery实现的简单分页示例
2016/06/01 Javascript
javascript中获取class的简单实现
2016/07/12 Javascript
浅谈Javascript数据属性与访问器属性
2016/07/26 Javascript
jQuery实现的表头固定效果实例【附完整demo源码下载】
2016/08/01 Javascript
基于JS实现仿百度百家主页的轮播图效果
2017/03/06 Javascript
详解React开发必不可少的eslint配置
2018/02/05 Javascript
Layui实现数据表格默认全部显示(不要分页)
2019/10/26 Javascript
JS中循环遍历数组的四种方式总结
2021/01/23 Javascript
python动态网页批量爬取
2016/02/14 Python
python操作redis方法总结
2018/06/06 Python
使用Pyhton集合set()实现成果查漏的例子
2019/11/24 Python
HTML5 Canvas 实现圆形进度条并显示数字百分比效果示例
2017/08/18 HTML / CSS
HTML5超炫酷粒子效果的进度条的实现示例
2019/08/23 HTML / CSS
ASOS亚洲:ASOS Asia
2018/03/04 全球购物
Anthropologie英国:美国家喻户晓的休闲服装和家居产品品牌
2018/12/05 全球购物
YSL圣罗兰美妆英国官网:Yves Saint Laurent Beauty UK
2019/08/03 全球购物
求职简历自荐信
2013/10/20 职场文书
小学生竞选班干部演讲稿
2014/04/24 职场文书
求职意向书范本
2015/05/11 职场文书
你对自己的信用报告有过了解吗?
2019/07/09 职场文书
muduo TcpServer模块源码分析
2022/04/26 Redis
Win10服务主机占用内存怎么办?Win10服务主机进程占用大量内存解决方法
2022/09/23 数码科技