首页 web前端 js教程 this和执行上下文实现代码_javascript技巧

this和执行上下文实现代码_javascript技巧

May 16, 2016 pm 06:24 PM
this 上下文

函数的执行上下文由当前的运行环境而定:
1. 全局变量和全局函数附属于全局对象(window),因此使用”var”或”this”两种方法定义全局变量是等效的。
2. 执行上下文和作用域不同。执行上下文在运行时确定,随时可能改变,而作用域则在定义时确定,永远不会变。
3. 如果当前执行的是一个对象的方法,则执行上下文就是这个方法所附属的对象。
4. 如果当前是一个创建对象的过程或者执行一个对象的方法,则执行上下文就是这个正在被创建的对象。
5. 如果一个方法在执行时没有明确指定附属对象,则这个方法的上下文为全局对象。
6. 使用call和apply可以改变对象的执行上下文。
看下面的例子:

复制代码 代码如下:

var v1 = "global variable"; //全局变量附属于对象
//this.v1 = "global variable with this"; //全局变量定义时使用var v1和this.v1两种方法等效。
function func1(){
var v1 = "part variable";
writeHtml(v1);
writeHtml(this.v1);
}
func1(); //part variable
//global variable

因为func1中有和全局对象同名的v1变量,所以在func1中直接引用v1引用的是func1中定义的变量。javascript同样有局部变量隐藏全局变量的特性。但func1没有明确的指定附属对象,因此他的执行上下文是全局对象,使用this引用变量的是全局变量。
再看一个稍微复杂一点的例子:
复制代码 代码如下:

function ftest(){
var v = "v1v1v1";
this.this_v = "this_v";
return function(){
writeHtml(v);
writeHtml(this.this_v);
}
}
var a = ftest();
var v = "v2v2v2";
writeHtml(this_v); // this_v
a(); //v1v1v1
//this_v

当ftest当做函数来执行时,上下文为全局对象。所以在ftest中使用this定义的变量成为了全局变量。所以我们在ftest外面直接使用变量名访问this_v的值。但是,由于ftest中返回的匿名函数是定义在ftest内部的,所以这个匿名函数的作用域就是在ftest内部。因此当有全局变量v和局部变量v同名时,这个匿名函数访问到的是ftest内部定义的变量v。
接下来把ftest当做类,使用new关键字来实例化:
复制代码 代码如下:

function ftest(){
var v = "v1v1v1";
this.this_v = "this_v";
return function(){
writeHtml(v);
writeHtml(this.this_v);
}
}
var a = new ftest();
var v = "v2v2v2";
//writeHtml(this_v); // 错误:this_v未定义
a(); //v1v1v1
//undefined

把ftest当做对象来实例化时,在对象的创建过程中,上下文为被创建的对象本身。注意,这个时候创建的对象是ftest的实例,而创建完成以后又返回了一个函数,这导致了new ftest()实例化后返回的是一个函数,而不是ftest()实例化后对象的引用。因此,这个已经实例化的对象无法被引用。当我们定义这个被返回的函数时,因为没有用this指定这个函数的上下文,因此这个被返回的函数上下文为全局对象,作用域为ftest()函数内部。所以函数a()执行时的由于上下文中没有定义this_v变量,导致了访问错误。
注意,上面的代码:
复制代码 代码如下:

function ftest(){
return function(){
}
}

这样的形式并不是一个静态封装环境,静态封装环境应该是:在一个函数定义完成后立即执行,并且执行完成后返回函数中的某一个内部函数。
我们看下面一个例子,观察作用域和上下文对变量引用的影响。
复制代码 代码如下:

var v = "global variable";
function method(){
writeHtml(v);
writeHtml(this.v);
}
var Class1 = function(){
var v = "private variable";
this.v = "object variable";

var method2 = method;
this.method2 = method;

var method3 = function(){
writeHtml(v);
writeHtml(this.v);
}
this.method3 = function(){
writeHtml(v);
writeHtml(this.v);
}

method2(); //global variable
//global variable
this.method2(); //global variable
//object variable
method3(); //private variable
//global variable
this.method3();//private variable
//object variable
}
var obj = new Class1();


由于method在全局中定义,所以method的作用域在定义的时候就被确定为全局的。所以method2在Class1内部被调用时,其作用域与是全局,上下文是全局对象。因此,在函数中访问到的变量都是全局变量。
同理,this.method2在被调用时,其作用域是全局,但是由于该函数在定义时使用this关键字指明了其上下文为Class1的对象,所以在该函数访问没有上下文限定的变量时访问到的是全局变量,访问有上下文限定的变量时为访问到的是当前上下文中对应的变量。
在调用method3和this.method3时,在访问没有上下文限定的变量时访问到的是局部变量,因为局部变量隐藏了全局变量。有上下文限定时和method2相同,访问到的是当前上下问文中的变量。
使用call和apply可以改变执行上下文,由于call和apply只是参数类型不一样,因此例子下面都用call来演示。
复制代码 代码如下:

var v = "global variable";
var method = function(){
writeHtml(this.v);
}
var Class2 = function(){
this.v = "object variable in instance of Class2";
this.method = function(){
writeHtml(this.v);
}
}
var Class3 = function(){
this.v = "object variable in instance of Class3";
this.method = function(){
writeHtml(this.v);
}
}

var obj2 = new Class2();
var obj3 = new Class3();

method(); //global variable
obj2.method(); //object variable in instance of Class2
obj3.method(); //object variable in instance of Class3

method.call(obj2); //object variable in instance of Class2
method.call(obj3); //object variable in instance of Class3
obj2.method.call(obj3); //object variable in instance of Class3
obj2.method.call(this); //global variable
obj3.method.call(obj2); //object variable in instance of Class2
obj3.method.call(this); //global variable


可以看到,使用call或apply可以将方法绑定到指定的上下文中。在全局环境中this指向的上下文为全局对象。
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

将自定义上下文菜单项添加到 Windows 11 的文件资源管理器菜单 将自定义上下文菜单项添加到 Windows 11 的文件资源管理器菜单 Apr 25, 2023 pm 06:19 PM

微软在启动Windows11操作系统时更改了文件资源管理器中的上下文菜单。文件资源管理器在Windows11中有两个上下文菜单:当用户右键单击文件管理器中的文件或文件夹时,新的紧凑菜单首先打开。可以从该新菜单或使用快捷方式打开经典上下文菜单。还有一个选项可以在Windows11的文件资源管理器中恢复经典上下文菜单,使其默认打开。程序可以将它们的条目添加到新的上下文菜单中,但它们需要有正确的编程才能这样做。Windows11用户可以使用Windows应用程序自定义上下文菜单将他们的

微软承诺让 Windows 11 右键菜单更快 微软承诺让 Windows 11 右键菜单更快 May 01, 2023 am 11:13 AM

Windows11继续定期更新,有报道称SunValley2将解决新操作系统的大部分主要问题。Windows11带来了几项设计大修,包括新的开始菜单、通知中心、任务栏和现代上下文菜单。上下文菜单是操作系统界面(尤其是文件资源管理器)的核心部分,并且已更新为新设计,这似乎导致性能缓慢。当您在文件资源管理器中右键单击文件或文件夹时,Windows11的上下文菜单会出现问题。作为其操作系统现代化努力的一部分,微软减少了上下文菜单中的选项数量,并开始使用图标/按钮来进行复制或可爱等选项。虽然此

Windows 11:如何从文件资源管理器的上下文菜单中删除使用 Clipchamp 编辑 Windows 11:如何从文件资源管理器的上下文菜单中删除使用 Clipchamp 编辑 May 03, 2023 pm 05:07 PM

Clipchamp是微软Windows11操作系统的新默认应用程序。微软于2021年购买了基于网络的视频编辑器,并于2022年初将其集成到Windows11的开发版本中。Clipchamp的免费版本当时并不能真正使用,因为它有太多的限制。它为所有视频加水印并将导出限制为480p。Microsoft取消了一些限制并更改了可用计划。导出现在支持1080p,免费版导出不再添加水印。微软将Clipchamp作为Windows112022更新中的默认应用程序。Windows1

这个小应用程序为旧的 Windows 10 和 11 上下文菜单添加了亚克力效果 这个小应用程序为旧的 Windows 10 和 11 上下文菜单添加了亚克力效果 May 16, 2023 pm 06:37 PM

尽管微软夜以继日地致力于使Windows11更加现代和精美,但该操作系统在其表皮下保留了旧时代的残余。例如,有两种上下文菜单:一种是现代的,一种是传统的。如果您对Windows11(和Windows10)中旧菜单的外观不满意,这里有一个小型开源应用程序(通过OnMsft ),感谢他们使用Acrylic效果使它们更漂亮。TranslucentFlyouts是一个小型应用程序,可以用半透明效果替换看起来单调的纯色背景。您可以个性化样式(Acrylic、Aero、Transpare

Windows 11 版本 22H2:文件资源管理器更改 Windows 11 版本 22H2:文件资源管理器更改 May 01, 2023 pm 08:04 PM

在该系列的第四部分,我们将了解默认文件管理器工具文件资源管理器以及微软计划在Windows112022更新中引入的更改。微软在2021年推出新的Windows11操作系统时,在几个关键领域对文件资源管理器进行了更改。最突出的变化之一是引入了紧凑的上下文菜单,文件资源管理器默认显示该菜单。提示:以下是在Windows11中恢复经典文件资源管理器上下文菜单的说明。这一变化并不是唯一的变化,因为微软简化了文件资源管理器的主工具栏,这导致许多项目只有在额外点击一两次后才能访问。希望微软在即

一篇搞懂this指向,赶超70%的前端人 一篇搞懂this指向,赶超70%的前端人 Sep 06, 2022 pm 05:03 PM

同事因为this指向的问题卡住的bug,vue2的this指向问题,使用了箭头函数,导致拿不到对应的props。当我给他介绍的时候他竟然不知道,随后也刻意的看了一下前端交流群,至今最起码还有70%以上的前端程序员搞不明白,今天给大家分享一下this指向,如果啥都没学会,请给我一个大嘴巴子。

聊聊Vue2为什么能通过this访问各种选项中属性 聊聊Vue2为什么能通过this访问各种选项中属性 Dec 08, 2022 pm 08:22 PM

本篇文章带大家解读vue源码,来介绍一下Vue2中为什么可以使用 this 访问各种选项中的属性,希望对大家有所帮助!

Java中this方法怎么使用 Java中this方法怎么使用 Apr 18, 2023 pm 01:58 PM

一、this关键字1.this的类型:哪个对象调用就是哪个对象的引用类型二、用法总结1.this.data;//访问属性2.this.func();//访问方法3.this();//调用本类中其他构造方法三、解释用法1.this.data这种是在成员方法中使用让我们来看看不加this会出现什么样的状况classMyDate{publicintyear;publicintmonth;publicintday;publicvoidsetDate(intyear,intmonth,intday){ye

See all articles