首先一起回顾下预解析作用域吧:

  预解析:
    浏览器每读到一个script标签或function,先不执行任何代码,会先把整个代码快速的浏览一遍,然后从中 挑出 var 和 function两个关键字 .
    var: 预解析遇到 var 就把 var 连同它后边的名字一块 提到script(或function) 的最前边,预解析完成之后,在从上向下一行一行执行代码,如果碰到了 = 就赋值;
    function:预解析遇到function,就把整个函数提到提到script(或function) 的最前边(跟在var的后边预解析先解析var 在解析 function)

    全局作用域 --- 在任何地方都能访问
                             函数外定义的变量拥有全局作用域
                            不使用var定义的变量拥有全局作用域
                            所有window对象上的属性拥有全局作用域
                            没有声明在任何函数内部的函数拥有全局作用域
      局部作用域 --- 只能在函数内部访问
                            使用var在函数内部定义的变量,和使用function在函数内部声明的函数,拥有局部作用域

[[Scopes]] : 作用域
                            当我们声明一个函数的时候,同时该函数就会创建一个属性这个属性是[[Scopes]](作用域),我们在这个函数中 声明的变量都会被存入这个函数的[[Scopes]]属性中
     变量与函数的查找规则:
                            当我们调用一条数据的时候,js首先会在当前作用域中进行查找,如果找不到,就向上找到父级的作用域,如果在父级的作用域中也找不到,就继续向上查找,直                               到window的作用域。如果在window中也找不到,就报错了

小例子中有涉及到箭头函数,所以我们先认识一下ES6中的箭头函数吧。

// 箭头函数
var fn3 = (a, b) => {
console.log(a, b);
} // 几种有条件的简化写法
// 当参数只有一个的时候
var fn4 = a => {
console.log(a);
}
// 当参数有多个的时候
var fn5 = (a, b) => {
console.log(a, b);
}
// 当没有参数的时候
var fn6 = () => {
console.log();
}
// 有且仅有一个形参的时候,可以省略参数的小括号 // var fn7 = r => {
// return r * r * Math.PI;
// }
// 只有一条语句的时候,可以省略{},同时该条语句的结果将作为该函数的返回值
var fn7 = r => r * r * Math.PI;

下面是箭头函数的特性,主要是this需要多加注意

    在es6中,提供了一种新的函数格式:箭头函数
注意:
1. 箭头函数不能作为构造函数,也就是箭头函数不能使用new运算符
2. 箭头函数的this永远指向当前申明作用域对象 带大括号的范围
1. 普通函数this指向取决于调用
2. 箭头函数this指向取决于申明
3. 箭头函数没有arguments对象
也会因为call的改变指向而改变this。即使在构造函数中。所谓的声明时候的this,也可能是被变化掉了。
 

接着,我们一起来看一个小例子吧!

var name='window';
var person1 = {
name:'person1',
show1: function() {
console.log(this.name)
},
show2: () => console.log(this.name),
show3: function() {
return function() {
console.log(this.name)//这里的this跟外层函数的this没关系
}
},
show4: function(){
return () => console.log(this.name)
}
};
//call是更改this指向的。 //对象属性中的函数,写法相当于 person1.show=function(){}
//函数是全局作用域,挂载到window下,方便理解后面的this指向window var person2 = {name:'person2'};
person1.show1()//person1
//person1是个对象所以这里指向的是对象的this person1 person1.show1.call(person2)//person2
//函数执行前先改了this指向 person1.show2()//window
//函数声明是挂载到window下的,箭头函数与声明作用域对象有关
//即使这里调用该函数执行的是对象,但this还是指的window person1.show2.call(person2)//window
//同上,虽然执行函数时更改了this指向,但是这一套对箭头不好使。所以仍然是window person1.show3()()//window
//person1.show3()得到的其实是function(){console.log(this.name)}
//函数执行,this指向的就是window person1.show3().call(person2)//person2
//person1.show3()得到的其实是function(){console.log(this.name)}
//然而接着在执行function前更改了指向 person1.show3.call(person2)()//window
//person1.show3.call(person2)更改了function() {
// return function() {
// console.log(this.name)
// }
// }
//但再次调用括号执行本质还是跟上面一样,执行的是return出来的内部函数
//先更改的指向是障眼法而已 person1.show4()()//person1
//person1.show4()先执行得到的是() => console.log(this.name)
//再指向该箭头函数,它的声明作用域this指向的是person1 person1.show4().call(person2)//person1
//箭头函数this在声明时候指向的是person1。
//person1.show4()先执行得到的是() => console.log(this.name)
//这里的call是更改箭头函数本身的指向,是改不了的。 person1.show4.call(person2)()//person2
//person1.show4.call(person2)第一步执行这个的时候就先更改了指向
//在执行() => console.log(this.name)前先更改了person1的指向

 

对比: 上面第一个是一个对象而已,所以show2的箭头函数声明时直接指向的window, 下面的是构造函数,能够为s1的箭头函数提供执行环境,所以这里指向的是TImer对象本身。

       以上两种情况是需要注意区别的。

有错误或者不足之处请大家多多指正,谢谢啦!!!

函数作用域中的this问题的更多相关文章

  1. Javascript中的词法作用域、动态作用域、函数作用域和块作用域(四)

    一.js中的词法作用域和动态作用域      词法作用域也就是在词法阶段定义的作用域,也就是说词法作用域在代码书写时就已经确定了.       js中其实只有词法作用域,并没有动态作用域,this的执 ...

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

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

  3. JS _函数作用域及变量提升

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

  4. 浅谈JavaScript 函数作用域当中的“提升”现象

    在JavaScript当中,定义变量通过var操作符+变量名.但是不加 var 操作符,直接赋值也是可以的. 例如 : message = "hello JavaScript ! " ...

  5. 关于JavaScript全局作用域和函数作用域的拙见

    在类c的语言中,用{}引起来的部分称为块级作用域,而在JS中没有块级作用域 作用域:一个变量作用的范围:中Js中一共有两种作用: 全局作用域 - 直接编写在script标签中的JS代码,都在全局作用域 ...

  6. JavaScript 函数作用域的“提升”现象

    在JavaScript当中,定义变量通过var操作符+变量名.但是不加 var 操作符,直接赋值也是可以的.例如 : message = "hello JavaScript ! " ...

  7. JS基础_函数作用域

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. js高级程序设计书中,有一句话在全局作用域中定义的函数实际上只 能被某个对象调用???

    js没有块级作用域(题外话:函数可以作为一个块级),所以我们经常使用闭包来模拟块级作用域,以避免变量或者函数因为名称相同而产生的冲突. 重点来了: 所以,如果我们把哪个变量或者函数放在全局作用域中,那 ...

  9. javascript中不存在块级作用域,所以要小心使用在块级作用域中的函数声明所带来的作用域混乱.

    在javascript中函数的作用域是一个非常重要的概念. javascript中是没有块级作用域,但是有函数作用域的概念. 我们在开发的过程中,经常会遇到这样的问题, 某个函数我暂时不需要,不想声明 ...

随机推荐

  1. (转)如何将 Excel 文件导入到 Navicat for MySQL 数据库

    场景:工作中需要统计一段时间的加班时长,人工统计太过麻烦,就想到使用程序实现来统计 1 如何将 Excel 文件导入到 Navicat for MySQL 数据库 Navicat for MySQL  ...

  2. 配置LAMP实现WordPress

    环境说明: 在同一台主机上实现LAMP(Linux + Apache + MariaDB + PHP) CentOS 7.3.Apache 2.4.6.MariaDB 5.5.52.PHP 5.4.1 ...

  3. php+sqlserver实现分页效果

    找了一些实现的代码,都或多或少有点问题. 主要问题在于: 在进行一页数据查询时的sql语句格式问题, 开始尝试使用limit关键字查询,错误,limit用于mysql: 接着使用ROWNUM.row_ ...

  4. Android学习笔记-ScrollView(滚动条)

    本节引言: 本节带来的是Android基本UI控件中的第十个:ScrollView(滚动条),或者我们应该叫他 竖直滚动条,对应的另外一个水平方向上的滚动条:HorizontalScrollView, ...

  5. No simulation input file assignm…

    QuartusII中仿真时出现No simulation input file assignment specified on simulator page of the settings dialo ...

  6. hdu2108 Shape of HDU 极角排序判断多边形

    Problem Description 话说上回讲到海东集团推选老总的事情,最终的结果是XHD以微弱优势当选,从此以后,"徐队"的称呼逐渐被"徐总"所取代,海东 ...

  7. 种下一棵树:有旋Treap

    第一个平衡树板子,有旋Treap.用随机函数规定一个堆,维护点权的同时维护堆的性质,可以有效地避免退化成链.按我的理解,建立一棵二叉排序树,树的形态会和给出节点的顺序有关.按照出题人很机智定理,数据肯 ...

  8. Javascript DOM 编程艺术———总结-2

    第三章: 一,DOM: Document(文档) Object(对象):用户定义对象,内建对象,宿主对象. Model(模型) 二,节点: 元素节点:诸如:<body> <p> ...

  9. 曲线点抽稀算法-Python实现

    何为抽稀 在处理矢量化数据时,记录中往往会有很多重复数据,对进一步数据处理带来诸多不便.多余的数据一方面浪费了较多的存储空间,另一方面造成所要表达的图形不光滑或不符合标准.因此要通过某种规则,在保证矢 ...

  10. C# 开机自启动和最小化托盘显示

    C# 开机自启动和最小化托盘显示 一.      C# 开机自启动 C# 开机自启动,这个功能是大多数服务型软件很常用一个功能,但是这个功能确是不 太好做,花了两天想对策.不过最终呢,结果还是很满意的 ...