js-this作用域

2014-5-7
this作用域以前专门学习研究过,但发现依然不够全面和完整。现在继续学习
先列出之前看过的结论:
函数在被调用的时候会意外接受两个参数:this和argument,其中this的值跟取决于函数的调用模式
1,方法调用模式 o.a() //this指的o
2,函数调用模式 a() //this指的windows
3,构造器调用模式 new a() //this为a的实例对象
4,apply(call)的间接调用模式 a.apply(xx,[yy]) //this指的xx

但是,上面的描述并没有指出背后的联系,换一种描述方式:
在这里列出this在ECMAScript中的不同含义:

(1) 在全局执行环境中使用this,表示Global对象,在浏览器中就是window对象。

(2) 当在函数执行环境中使用this时,情况就有些复杂了。如果函数没有明显的作为非window对象的属性,而只是定义了函数,不管这个函数是不是定义在另 一个函数中,这个函数中的this仍然表示window对象。如果函数显示地作为一个非window对象的属性,那么函数中的this就代表这个对象。 (当然可以使用apply或者call函数来取代默认this的引用,详见[P88])

(3) 当通过new运算符来调用函数时,函数被当做一个构造函数,this指向构造函数创建出来的对象。
参考:
《JavaScript基础与案例开发详解》清华大学出版社

定义一个函数,在不同的作用域中调用时this指代不同

当this使用在函数代码中事情就变得有趣多了。这种情况是最难的也会引发很多的问题。在函数代码中,this值的第一(可能也是最重要的)特性 就是不能 静态的绑定到一个函数上。正如上面已经提到的,this值在进入上下文时就已经被决定了,在函数代码的情形下,每次this值可以是完全不一样的。

然而,在代码运行时,this值是不可改变的。例如,不能给this赋一个新值,因为this不是变量(相反,python编程语言中,可以显式的定义self对象,在运行的时候self对象可重复改变)

Js代码  
  1. var foo={x:10};
  2. var bar={
  3. x:20,
  4. test:function(){
  5. console.log(this===bar);//true
  6. console.log(this.x);//20
  7. //this=foo;//error,不能改变this值
  8. }
  9. };
  10. //当进入上下文时,this值由"bar"对象决定的。为什么这样-将在下面详细讨论
  11. bar.test();//true,20
  12. foo.test=bar.test;
  13. //然而,此时在这里的this将指向"foo"-即使我们调用同一个函数
  14. foo.test();//false,10

(当我们在一些关于javascript 的文章和书本中会看到“this值由函数如何定义来决定:如果是全局函数,this值被设置为全局对象,如果函数时一个对象的方法,this值设置为这个 对象”-这是一个错误的描述)。从下面我们可以看出即使是一般的全局函数,也能够被产生不同this值的调用表达式所触发。

Js代码  
  1. function foo(){
  2. console.log(this);
  3. }
  4. foo();//打印this为Window
  5. console.log(foo===foo.prototype.constructor);//true
  6. //但是对于同一函数的另一种调用表达式形式,this值是不同的
  7. foo.prototype.constructor();//打印this为foo
  8. 调用一个被定义为对象方法的函数,但是this值不会被设置为这个对象也是同样可能的:
  9. var foo={
  10. bar:function(){
  11. console.log(this);
  12. console.log(this===foo);
  13. }
  14. };
  15. foo.bar();//foo,true
  16. var exampleFunc=foo.bar;
  17. console.log(exampleFunc===foo.bar);//true
  18. //同一函数的另一种调用表达式形式,得到不同的this值
  19. exampleFunc();//global,false

2013-09-10
最近看到一句话说,js中的对象其实就是一些hash映射。简单说就是名值对,只不过这些名字对同用一个上下文(context)this。

Js代码  
  1. var obj = {
  2. fun1 : function(){
  3. },
  4. fun2 : function(){
  5. //在使用fun1时,像使用自己的变量一样
  6. var local = this.fun1();//如果有参数,还可以传递参数
  7. },
  8. fun3 : function(){
  9. },
  10. };

2013-8-27
this关键字

每一个方法或函数都会有一个this对象,this对象是方法(或函数)在执行时的那个环境,也可以说是这个函数在那个作用域下运行的。
说的更通俗一点:this就相当于咱们平时说话时候说的“我”,“我家”的概念。就是说当一个方法在运行的时候,它是属于谁的。它在运行的时候它的家是谁家。
this的概念比较抽象,是讲课的时候的难点也是重点。
关于this的具体表示那个对象,和函数的运行方式(或调用方式)有关。

在JavaScript中一共有四种调用模式:
方法调用模式(对象属性模式)、
函数调用模式(就是普通的函数执行)、
构造调用模式(应该叫实例上的方法模式更好)
和apply调用模式。

一、当它为一个对象上的方法的时候,this是当前这个对象
方法调用模式(或称:对象属性模式)
先了解一个概念:方法和函数的区别。方法和函数本质一样,形式不同而已。看下例:

Js代码  
  1. function fn(){
  2. alert(this)
  3. }

这样就是定义了一个函数,当:fn()的时候,叫这个函数运行。同样是上面这个fn函数,如果把它赋值给一个对象的属性,就成了方法了,看下面的例子。

Js代码  
  1. var obj=new Object();//先定义一个对象obj
  2. obj.objFn=fn;

那现在的obj.objFn就是方法了,但其实objFn和fn指向的是同一个内存地址。但fn是直接定义的,就是函数,而objFn是obj这个对象上的一个属性,则objFn就是方法了。方法和函数本质上是一样的,只是在不同的情况下的叫法不同。
但当fn运行的时候,弹出的是window(任何函数被调用,this都表示window);而objFn运行的时候,弹出的是object,因 为当它做为一个方法运行的时候,this关键字表示的是objFn这个属性所属的这个对象obj。也就是说,在这种情况下,this表示obj。
再啰嗦一遍:当函数成为一个对象的属性的值的时候,这个函数里的this指向当前这个对象(这时候函数就变成了方法)
    再啰嗦第三遍:当一个函数被保存为对象的一个属性时,我们称它为一个方法。当一个方法被调用时,this被绑定到该对象。方法可以使用this去访问对 象,所以它能从对象中取值或修改对象。this到对象的绑定发生在调用的时候。这个“超级”迟绑定使得函数可以对this高度复用。通过this可取得它 们所属对象的上下文的方法称为公共方法。

二、函数调用模式
当函数并非一个对象的属性时,那么它被当做一个函数来调用。此模式下this绑定到全局对象。通过在对象内将this赋值给that,可以使函数模式下调用that来访问指定对象。
(就是上面解释的函数方式)

三、类的实例上的方法中的this指向当前的实例
例如:

Js代码  
  1. function Person(){
  2. }
  3. Person.prototype.cry=function (){alert(this)}
  4. var rose=new Person();
  5. rose.cry();//现在这个cry就被称做方法,这个方法里的this就表示rose这个实例。

详细的讲解,请见《面向对象和设计模式》的课堂讲解和视频

四、使用call和apply方法强制改变this关键字
(附在面向对象一章的讲解里)
测试题:
题目一:

Js代码  
  1. var name = "The Window";
  2.   var object = {
  3.     name : "My Object",
  4.     getNameFunc : function(){
  5.       return function(){
  6.         return this.name;
  7.      };
  8.     }
  9. };
  10. alert(object.getNameFunc()()); //The Window

解析:object.getNameFunc后面跟了两对括号。先运行object.getNameFunc(),这个方法运行后返回了一个函数,就是这个方法里面定义的那个匿名函数,然后再让这个匿名函数运行。
可以分解成以下步骤:

Js代码  
  1. var fn= object.getNameFunc();//object.getNameFunc这个方法里的this是表示object这个对象,但它返回的是一个函数,返回的这个函数里的这个this则表示window了
  2. fn();//当返回的这个函数运行的时候,this表示是window这个对象

和上一题目类似的题:

Js代码  
  1. function a(){
  2. alert(this);
  3. }
  4. var arr = [1,2,3];
  5. arr.f = a;
  6. arr.f();//会输出什么

解析:把a函数赋给arr的属性f,则f就成为arr这个对象上的方法了,它运行的时候就表示arr这个数组对象。
如果直接这样:a();  则这时候的this表示的是window这个对象

转载于:https://www.cnblogs.com/shsgl/p/4289870.html

js-this作用域相关推荐

  1. 1月8日学习内容整理:JS的作用域和作用域链

    补充: 对于编译型语言,是编译一次生成可执行文件来执行多次:对于解释型语言,始终都是编译一次执行一次 python编译时要看有没有赋值操作,没有的话就不编译任何内容:若有赋值操作,才会开辟内存空间,把 ...

  2. js 闭包作用域和作用域链_Java:伪造工厂的闭包以创建域对象

    js 闭包作用域和作用域链 最近,我们想创建一个域对象,该对象需要具有外部依赖关系才能进行计算,并且希望能够在测试中解决该依赖关系. 最初,我们只是在领域类中引入依赖关系,但这使得无法在测试中控制其值 ...

  3. JS中作用域以及变量范围

    变量作用域 js作为一门脚本语言,他与c,java这些语言是不相同的. 全局变量 在js中声明全局变量,有下面几种方式: 1.在函数外通过var来声明. var test ="hello&q ...

  4. 对“js变量作用域的疑问”的解答

    原文如下: 今天看到了FLASH AS关于变量作用域的讲解,突然想到一个js作用域的问题. 如下代码,猜猜执行后都弹出什么?   <script type="text/javascri ...

  5. js的作用域链,原型链,以及闭包函数理解

    代码一: this.number = 10 function a() {this.number = 20 } a.prototype.init = () => console.log(this. ...

  6. 你不知道的JS之作用域和闭包(二)词法作用域

    原文:你不知道的js系列 词法作用域(Lexical Scope) Lex time 一个标准的编译器的第一个阶段就是分词(token化) 词法作用域就是在词法分析时定义的作用域.换句话说,词法作用域 ...

  7. JavaScript之BOM对象(JS函数作用域、window、history、location对象)

    文章目录 一.JS作用域 二.window窗口 三.history对象 四.location对象 本篇文章来简单介绍一下JS作用域,以及BOM对象中的三个基础对象,分别是window对象.histor ...

  8. php js函数作用域,javascript 作用域详解

    作用域理解:定义的变量.函数生效的范围.javascript 有全局作用域和函数作用域两种. 注:es6实现let 块级作用域不是js原生的,底层同样是通过var实现的.如果想了解具体细节,请访问ba ...

  9. 详解JS的作用域和闭包

    序言 尽管通常将JavaScript归类为"动态"或"解释执行"语言,但实际上它是一门编程语言.但与传统的编译语言不同,它不是提前编译的,编译结果也不能在分布式 ...

  10. 你不懂JS:作用域与闭包 第五章:作用域闭包

    希望我们是带着对作用域工作方式的健全,坚实的理解来到这里的. 我们将我们的注意力转向这个语言中一个重要到不可思议,但是一直难以捉摸的,几乎是神话般的 部分:闭包.如果你至此一直跟随着我们关于词法作用域 ...

最新文章

  1. python拆堆和堆叠的操作_堆叠框架的Python / Tkinter退出按钮
  2. 自定义searchview包括修改图标样式
  3. Java代理模式/静态代理/动态代理
  4. Gradle 教程:第一部分,安装【翻译】
  5. vue组件之轮播图的实现
  6. spring boot 中启用 https
  7. ASP.NET Core 源码学习之 Options[4]:IOptionsMonitor
  8. Python Train_出乎意料的简单!10分钟用python建立人工智能预测模型
  9. java 泛型 擦除_Java泛型和类型擦除
  10. git规则写法_3条简单的规则将帮助您成为Git大师
  11. 12、基于yarn的提交模式
  12. VB快速查找大型文件中包含的字符串
  13. LeetCode 769. Max Chunks To Make Sorted
  14. 运动耳机品牌排名榜,2022年最值得入手的运动耳机推荐
  15. windows service (三)打包安装服务
  16. 剑指Offer28.对称的二叉树
  17. phpnow php升级,phpnow如何升级php版本
  18. Star Way To Heaven 题解
  19. angular使用echarts词云图wordCloud
  20. 2020年节假日JSON,全年日期对应的上班日、周末、节假日

热门文章

  1. okhttp builder_从 OkHttp 到 Retrofit 到 OkHttps
  2. java实现从头部及尾部删除指定长度字符
  3. IPC--进程间通信七 (socket)
  4. Golang练习题(自己认为比较不错的)
  5. 《汇编语言》王爽—第五章实验三详解
  6. 动态规划(DP)——通俗易懂!
  7. 备战蓝桥杯—有边数限制的最短路 (bellman_ford+)——[AcWing]有边数限制的最短路
  8. Circular buffer
  9. 广工计算机组成原理实验报告_计算机组成原理:存储器
  10. java控制面板作用_大师为你分析win7系统打开java控制面板的方法