函数的作用域与this指向是js中很重要的一部分,理清这点东西需要个逻辑,看看我的逻辑怎么样...

下面是个提纲,可以直接挑你感兴趣的条目阅读。

  • 函数的定义方式:直接定义(window下,内部定义),对象的方法,对象原型的方法;
  • 函数的调用方式:直接调用,call/apply,with
  • 对于直接定义的函数和对象的方法,作用域默认状态下是它的定义处的作用域链。
  • 对于直接定义的函数,this指向window。
  • 对于对象的方法,this指向实例化对象(对应于实例化对象默认返回this的情况)。
  • 用call/apply改变方法的this指向
  • 在函数或方法的定义时可以通过with改变其作用域链。

下面分开来具体说说:

函数的定义,如提纲中提到的可以分为两种:直接定义(window下,内部定义),对象的方法(或对象原型的方法)。从下面的示例代码中可以看到函数fn1与fn2以及对象的方法doFunction在函数使用name时name的值来自相应的域。

在使用name的值时将“name”用“this.name”来代替会出现什么情况呢,看下例:

从结果来看可以验证提纲中的第4和5条,也可以看到this和作用域是两套分离的链,遵循个自的变量查询逻辑,具体的查询逻辑在下面的性能分析中会提到,如果是新手建议先看一下“js的作用域链”方面的基础知识。

关于函数的调用方法,我用下面的方示例说明提纲中的第2、6条:

调用时call和apply的使用是为了改变被调用函数的this指向。with的使用是为了改变被调用函数中变量的查询域。我们把上例中的call和name前的this去掉再加上with来演示with的作用。

看到with的使用并不方便,需要在被调用函数中添加with,有人可能想能不能向下面那样调用来整体改变变量作用域而不去改变被调用函数呢?

with (myScope) {
fn1();
fn2();
var obj = new MyObj();
obj.doFunction();
}

很遗憾,不可以!所以在一些成熟的框架中随处可见call和apply的使用,却很少用到with,在用JSHint检测js语法的时候with处都标了小红点,在一些js编码指导中也建议尽量少用with,因为with改变了变量的默认查询链,所以会给后期的维护人员一些困惑,还有性能方面的一些考虑,请慎用with。

此文先到此为止,关于更深入的探索,与一些性能方面的注意事项请看我的另一篇博文:函数的作用域与this指向 --- 性能篇

js函数的作用域与this指向的更多相关文章

  1. 函数的作用域与this指向 --- 性能篇

    紧接上一篇博文:js函数的作用域与this指向 先来说说this的作用于链,this后的属性或者方法在使用时是先从本实例中查找,如果找到就先返回,如果没找到就接着向上从原型链中查找,如果有多重继承关系 ...

  2. js函数与作用域,了解函数基本概念

    通过js基础语法了解到js的值包含数字,字符串和布尔值;js运算符分为算数,赋值,比较和逻辑运算符;js的流程控制包含条件判断if,switch选择;循环for while:下面js的函数及作用域,学 ...

  3. 深入理解JS函数中this指针的指向

    函数在执行时,会在函数体内部自动生成一个this指针.谁直接调用产生这个this指针的函数,this就指向谁. 怎么理解指向呢,我认为指向就是等于.例如直接在js中输入下面的等式: console.l ...

  4. JS核心系列:浅谈函数的作用域

    一.作用域(scope) 所谓作用域就是:变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的. function scope(){ var foo = "global&quo ...

  5. js对象系列【二】深入理解js函数,详解作用域与作用域链。

    这次说一下对象具体的一个实例:函数,以及其对应的作用域与作用域链.简单的东西大家查下API就行了,这里我更多的是分享自己的理解与技巧.对于作用域和作用域链,相信绝大多数朋友看了我的分享都能基本理解,少 ...

  6. js总结(二):函数、作用域和this

    function Container( properties ) { var objthis = this; for ( var i in properties ) { (function(){ // ...

  7. 【js】 vue 2.5.1 源码学习(六) initProxy initLifeCycle 渲染函数的作用域代理

    大体思路 (五) 1. initProxy 渲染函数的作用域代理 ==> es6 如果支持proxy (hasProxy) 就用proxy 不支持就用 defineProperty() prox ...

  8. 在iframe里调用parent.func()引出的js函数运行在它们被定义的作用域里,而不是它们被执行的作用域里

    有个document里定义了一个函数func(),同时在document里嵌入了一个iframe,在这个iframe里调用父窗口的方法:parent.func(),本来我以为这个函数的运行环境是在这个 ...

  9. JS 函数作用域及变量提升那些事!

    虽然看了多次js函数作用域及变量提升的理论知识,但小编也是一知半解~ 这几天做了几道js小题,对这部分进行了从新的理解,还是有所收获的~ 主要参考书籍: <你不知道的JavaScript(上卷) ...

随机推荐

  1. ssh连接虚拟机失败解决办法

    首先,你需要知道本机IP跟虚拟机IP,然后让两者互相ping一下,看能否ping通 让主机ping虚拟机 :ping (虚拟机ip) 出现如下: 表示主机可以ping通虚拟机 然后让虚拟机ping主机 ...

  2. [DeeplearningAI笔记]ML strategy_2_3迁移学习/多任务学习

    机器学习策略-多任务学习 Learninig from multiple tasks 觉得有用的话,欢迎一起讨论相互学习~Follow Me 2.7 迁移学习 Transfer Learninig 神 ...

  3. HTML DOM应用案例1

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 阿里云ecs遭到频繁的ddos攻击始末

    苦逼熬夜近俩月的时间搞出来个小东东,还指望它能给自己捞点~  结果刚上线没多久就遭到竞争对手疯狂的ddos攻击. 可怜的阿里云默认只能抗住5G的攻击,超出的直接黑洞,也是很无奈,然而能免费抗5G这在国 ...

  5. asp.net应用发布到IIS无法链接到oracle数据库

    遇到这个问题纠结了好久,试了好多的方法,其中我的问题是,先安装了.net frameword4然后又安装的IIS. 正确方式应该是先安装IIS 然后安装.net framework;且应用程序池没有启 ...

  6. eclipse导出jar(含依赖)三步走

    之前用eclipse导出jar运行结果一直不尽人意,排查问题排查很久,最终确定到导出jar时,如果依赖jdk以外的jar时,就要通知eclipse 看了很多帖子,感觉操作起来都比较麻烦,注意点也比较多 ...

  7. Varnish 实战项目

    实现基于Keepalived+Haproxy+Varnish+LNMP企业级架构 原理:缓存,又称加速器,用于加速运行速度较快的设备与较慢设备之间的通信.基于程序的运行具有局部性特征其能实现加速的功能 ...

  8. Java 浏览器兼容模式

    现在设计的东西,很多浏览器不兼容.下面贴出代码.测试在360和IE浏览器下,可以兼容的 <!doctype html><html><head>    <met ...

  9. 深入理解Postgres中的cache

    众所周知,缓存是提高数据库性能的一个重要手段.本文着重讲一讲PostgreSQL中的缓存相关的东西.当然万变不离其宗,原理都是共同的,理解了这些,你也很容易把它运用到其它数据库中. What is a ...

  10. 项目详解4—haproxy 详解

    一.企业服务架构图及负载均衡的要求 1.场景说明 在企业生产环境中,每天会有很多的需求变更,比如增加服务器.新业务上线.url路由修改.域名配置等等,对于前端负载均衡设备来说,容易维护,复杂度低,是首 ...