js-this作用域
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对象可重复改变)
- var foo={x:10};
- var bar={
- x:20,
- test:function(){
- console.log(this===bar);//true
- console.log(this.x);//20
- //this=foo;//error,不能改变this值
- }
- };
- //当进入上下文时,this值由"bar"对象决定的。为什么这样-将在下面详细讨论
- bar.test();//true,20
- foo.test=bar.test;
- //然而,此时在这里的this将指向"foo"-即使我们调用同一个函数
- foo.test();//false,10
(当我们在一些关于javascript 的文章和书本中会看到“this值由函数如何定义来决定:如果是全局函数,this值被设置为全局对象,如果函数时一个对象的方法,this值设置为这个 对象”-这是一个错误的描述)。从下面我们可以看出即使是一般的全局函数,也能够被产生不同this值的调用表达式所触发。
- function foo(){
- console.log(this);
- }
- foo();//打印this为Window
- console.log(foo===foo.prototype.constructor);//true
- //但是对于同一函数的另一种调用表达式形式,this值是不同的
- foo.prototype.constructor();//打印this为foo
- 调用一个被定义为对象方法的函数,但是this值不会被设置为这个对象也是同样可能的:
- var foo={
- bar:function(){
- console.log(this);
- console.log(this===foo);
- }
- };
- foo.bar();//foo,true
- var exampleFunc=foo.bar;
- console.log(exampleFunc===foo.bar);//true
- //同一函数的另一种调用表达式形式,得到不同的this值
- exampleFunc();//global,false
2013-09-10
最近看到一句话说,js中的对象其实就是一些hash映射。简单说就是名值对,只不过这些名字对同用一个上下文(context)this。
- var obj = {
- fun1 : function(){
- },
- fun2 : function(){
- //在使用fun1时,像使用自己的变量一样
- var local = this.fun1();//如果有参数,还可以传递参数
- },
- fun3 : function(){
- },
- };
2013-8-27
this关键字
每一个方法或函数都会有一个this对象,this对象是方法(或函数)在执行时的那个环境,也可以说是这个函数在那个作用域下运行的。
说的更通俗一点:this就相当于咱们平时说话时候说的“我”,“我家”的概念。就是说当一个方法在运行的时候,它是属于谁的。它在运行的时候它的家是谁家。
this的概念比较抽象,是讲课的时候的难点也是重点。
关于this的具体表示那个对象,和函数的运行方式(或调用方式)有关。
在JavaScript中一共有四种调用模式:
方法调用模式(对象属性模式)、
函数调用模式(就是普通的函数执行)、
构造调用模式(应该叫实例上的方法模式更好)
和apply调用模式。
一、当它为一个对象上的方法的时候,this是当前这个对象
方法调用模式(或称:对象属性模式)
先了解一个概念:方法和函数的区别。方法和函数本质一样,形式不同而已。看下例:
- function fn(){
- alert(this)
- }
这样就是定义了一个函数,当:fn()的时候,叫这个函数运行。同样是上面这个fn函数,如果把它赋值给一个对象的属性,就成了方法了,看下面的例子。
- var obj=new Object();//先定义一个对象obj
- 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指向当前的实例
例如:
- function Person(){
- }
- Person.prototype.cry=function (){alert(this)}
- var rose=new Person();
- rose.cry();//现在这个cry就被称做方法,这个方法里的this就表示rose这个实例。
详细的讲解,请见《面向对象和设计模式》的课堂讲解和视频
四、使用call和apply方法强制改变this关键字
(附在面向对象一章的讲解里)
测试题:
题目一:
- var name = "The Window";
- var object = {
- name : "My Object",
- getNameFunc : function(){
- return function(){
- return this.name;
- };
- }
- };
- alert(object.getNameFunc()()); //The Window
解析:object.getNameFunc后面跟了两对括号。先运行object.getNameFunc(),这个方法运行后返回了一个函数,就是这个方法里面定义的那个匿名函数,然后再让这个匿名函数运行。
可以分解成以下步骤:
- var fn= object.getNameFunc();//object.getNameFunc这个方法里的this是表示object这个对象,但它返回的是一个函数,返回的这个函数里的这个this则表示window了
- fn();//当返回的这个函数运行的时候,this表示是window这个对象
和上一题目类似的题:
- function a(){
- alert(this);
- }
- var arr = [1,2,3];
- arr.f = a;
- arr.f();//会输出什么
解析:把a函数赋给arr的属性f,则f就成为arr这个对象上的方法了,它运行的时候就表示arr这个数组对象。
如果直接这样:a(); 则这时候的this表示的是window这个对象
转载于:https://www.cnblogs.com/shsgl/p/4289870.html
js-this作用域相关推荐
- 1月8日学习内容整理:JS的作用域和作用域链
补充: 对于编译型语言,是编译一次生成可执行文件来执行多次:对于解释型语言,始终都是编译一次执行一次 python编译时要看有没有赋值操作,没有的话就不编译任何内容:若有赋值操作,才会开辟内存空间,把 ...
- js 闭包作用域和作用域链_Java:伪造工厂的闭包以创建域对象
js 闭包作用域和作用域链 最近,我们想创建一个域对象,该对象需要具有外部依赖关系才能进行计算,并且希望能够在测试中解决该依赖关系. 最初,我们只是在领域类中引入依赖关系,但这使得无法在测试中控制其值 ...
- JS中作用域以及变量范围
变量作用域 js作为一门脚本语言,他与c,java这些语言是不相同的. 全局变量 在js中声明全局变量,有下面几种方式: 1.在函数外通过var来声明. var test ="hello&q ...
- 对“js变量作用域的疑问”的解答
原文如下: 今天看到了FLASH AS关于变量作用域的讲解,突然想到一个js作用域的问题. 如下代码,猜猜执行后都弹出什么? <script type="text/javascri ...
- js的作用域链,原型链,以及闭包函数理解
代码一: this.number = 10 function a() {this.number = 20 } a.prototype.init = () => console.log(this. ...
- 你不知道的JS之作用域和闭包(二)词法作用域
原文:你不知道的js系列 词法作用域(Lexical Scope) Lex time 一个标准的编译器的第一个阶段就是分词(token化) 词法作用域就是在词法分析时定义的作用域.换句话说,词法作用域 ...
- JavaScript之BOM对象(JS函数作用域、window、history、location对象)
文章目录 一.JS作用域 二.window窗口 三.history对象 四.location对象 本篇文章来简单介绍一下JS作用域,以及BOM对象中的三个基础对象,分别是window对象.histor ...
- php js函数作用域,javascript 作用域详解
作用域理解:定义的变量.函数生效的范围.javascript 有全局作用域和函数作用域两种. 注:es6实现let 块级作用域不是js原生的,底层同样是通过var实现的.如果想了解具体细节,请访问ba ...
- 详解JS的作用域和闭包
序言 尽管通常将JavaScript归类为"动态"或"解释执行"语言,但实际上它是一门编程语言.但与传统的编译语言不同,它不是提前编译的,编译结果也不能在分布式 ...
- 你不懂JS:作用域与闭包 第五章:作用域闭包
希望我们是带着对作用域工作方式的健全,坚实的理解来到这里的. 我们将我们的注意力转向这个语言中一个重要到不可思议,但是一直难以捉摸的,几乎是神话般的 部分:闭包.如果你至此一直跟随着我们关于词法作用域 ...
最新文章
- python拆堆和堆叠的操作_堆叠框架的Python / Tkinter退出按钮
- 自定义searchview包括修改图标样式
- Java代理模式/静态代理/动态代理
- Gradle 教程:第一部分,安装【翻译】
- vue组件之轮播图的实现
- spring boot 中启用 https
- ASP.NET Core 源码学习之 Options[4]:IOptionsMonitor
- Python Train_出乎意料的简单!10分钟用python建立人工智能预测模型
- java 泛型 擦除_Java泛型和类型擦除
- git规则写法_3条简单的规则将帮助您成为Git大师
- 12、基于yarn的提交模式
- VB快速查找大型文件中包含的字符串
- LeetCode 769. Max Chunks To Make Sorted
- 运动耳机品牌排名榜,2022年最值得入手的运动耳机推荐
- windows service (三)打包安装服务
- 剑指Offer28.对称的二叉树
- phpnow php升级,phpnow如何升级php版本
- Star Way To Heaven 题解
- angular使用echarts词云图wordCloud
- 2020年节假日JSON,全年日期对应的上班日、周末、节假日
热门文章
- okhttp builder_从 OkHttp 到 Retrofit 到 OkHttps
- java实现从头部及尾部删除指定长度字符
- IPC--进程间通信七 (socket)
- Golang练习题(自己认为比较不错的)
- 《汇编语言》王爽—第五章实验三详解
- 动态规划(DP)——通俗易懂!
- 备战蓝桥杯—有边数限制的最短路 (bellman_ford+)——[AcWing]有边数限制的最短路
- Circular buffer
- 广工计算机组成原理实验报告_计算机组成原理:存储器
- java控制面板作用_大师为你分析win7系统打开java控制面板的方法