理解JavaScript中this的指向详解

 

this的定义和理解:

this是JavaScript语言的一个关键字,它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内使用。

 

1、this和执行环境对象有关,和函数的声明无关。

   var name="Tom";var Bob={name:'Bob',show:function(){console.log(this.name);}};var show=Bob.show;   //等同于var show=function(){console.log(this.name);}show();   //输出的是Tom,全局对象调用show()函数window.Bob.show();   //输出是 Bob ,函数执行对象是Bobvar someone={name:"盖伦",say:function(){console.log(this.name);}};var otherone={name:"杰克",speak:someone.say  //等同于声明函数speak:function(){console.log(this.name);}};otherone.speak();  //输出 杰克 ,函数被执行时this指向调用的对象otherone

上述代码解析:函数执行时,this指向的是函数运行时所在的当前环境对象。注意this和执行环境有关,和函数的声明无关。。也可以理解为this指向的是调用它的对象!

 

2、函数没有明确的执行对象时,this指向全局对象window。

   var a=11;function test1(){var person="zhangsan";console.log(this);      //输出全局对象windowconsole.log(this.person);   //undefinedconsole.log(this.a);    // 11}test1();   //没有明确函数执行对象时,this指向window全局对象window.test1(); //作用同上var name="Jack";var Rose={name:'rose',showName:function(){console.log(this.name);}};var Jane={name:'Jane',showName:function(){var fun=Rose.showName;  //等同于var fun=function(){console.log(this.name);}fun();  //在Jane.showName声明时执行了,没有明确的执行对象,this指向全局对象window}};Jane.showName();var obj = {a:10,b:{a:12,fn:function(){console.log(this.a); //undefinedconsole.log(this); //window}}}var j = obj.b.fn;  //等同于 j=function(){console.log(this.a);console.log(this);}   j();  //所以this指向window, this.a是undefined

上述代码解析:没有明确的执行对象时,this指向全局对象window。浏览器中window是js中的全局对象,创建的对象和声明的函数实际是在给window添加属性;

 

3、定时器setTimeout 、setInterval 和匿名函数执行时的当前对象是全局对象window,定时器也可以理解为延迟执行的匿名函数

   var name="Jack";var nameObj={name:'rose',showName:function(){console.log(this.name);},waitShowName:function(){setTimeout(this.showName,5000);  //等同于延迟执行function(){...}(this.showName)的匿名函数}};nameObj.waitShowName();  //输出 Jack ,定时器和匿名函数执行的当前对象是window全局对象(function(val){if(val>10){console.log(this);  //输出window}})(55);

如何使定时器中的执行对象不是window对象,可以通过var that=this; 的形式保存定时器所在函数的对象,定时器中匿名函数使用that获取定时器所在的对象

var name = "Bob";  
var nameObj ={  name : "Tom",  showName : function(){  alert(this.name);  },  waitShowName : function(){var that = this;         //保存调用waitShowName()函数时的对象到that//定时器使用时,使用that也就是定时器所在对象nameObj,而不是windowsetTimeout(function(){that.showName();}, 1000);}
}; nameObj.waitShowName();  //Tom

4、构造函数使用new关键词创建对象后,构造函数中的this指向该构造函数创建出来的新对象

   function Person(val){this.name=val}Person.prototype.show=function(){console.log(this.name);};var zhangsan=new Person("zhangsan"); //new关键词会根据构造函数创建一个新对象,this指向新对象zhangsan.show();

如果构造函数中使用return 返回一个对象,new 关键词创建的新对象会被return返回的对象替换,return返回的是非对象时this指向new创建的新对象,如下

function fn(){  this.name = 'Tom';  return {name:'xiaohong',showName:function(){console.log(this.name);}};  
}
var a = new fn;  
a.showName(); //输出 xiaohongfunction fn(){  this.name = 'Tom';  return false;  //return 返回非对象
}
var a = new fn;  
console.log(a.name);  //输出 Tom

 

5、eval() 函数 和 new Function() 使用字符串作为执行的代码体

eval() 函数计算 JavaScript 字符串,并把它作为脚本代码来执行如果参数是一个表达式,eval() 函数将执行表达式。如果参数是Javascript语句,eval()将执行 Javascript 语句。

   var a=eval('2+8');  //eval函数使用string作为参数,可以计算表达式或者执行js语句var b=eval('console.log("这是使用eval函数直接执行js语句获取的结果");');console.log(a);

类似 eval()函数,new Function() 可以将字符串当做代码(函数体)来执行。最后一个string参数做函数体,其他参数做该函数的参数

   //Function 这个构造函数可以用来创建函数对象//一个参数都不传的时候,创建了一个fn0的函数var fn0=new Function();console.log(typeof fn0);  //function//这里是创建了一个fn1的函数,只传一个参数string时,函数体就是传入的字符串形式的js语句var fn1=new Function("console.log('666666');");  fn1();  //输出 666666//传入多个参数的时候,最后一个参数作为函数体,前面的参数都作为该函数的参数var fn2=new Function("a","b","return a + b;"); console.log(fn2(10,90));   //输出100

 

 

7、call() 和applay() 方法可以改变this指向。这里不细说,

后续会有一篇call、applay、bind改变this指向的文章详细分析,这里简单提一下

var name = "window";var someone = {name: "Bob",showName: function(){alert(this.name);}
};var other = {name: "Tom"
};    someone.showName.apply();    //window
someone.showName.apply(other);    //Tom ,applay方法使得this指向为other对象

apply和call方法都用于改变函数执行时的当前对象,当无参数时,当前对象为window,有参数时当前对象为该参数。于是这个例子Bob成功偷走了Tom的名字;

 

参考网址:http://www.cnblogs.com/justany/archive/2012/11/01/the_keyword_this_in_javascript.html

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/554048.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何设置PP视频允许PPAP驻留

今天继续给大家分享PP视频方面的内容。   如何设置PP视频允许PPAP驻留,将让下次启动时更加快速,下面让我们一起看看,是如何设置的吧 1、点击“PP视频” 2、在“PP视频”播放窗口中,点击“菜单”按钮 3、在弹出下拉栏中&#…

深入理解call、apply、bind(改变函数中的this指向)

在JavaScript中call、apply、bind是Function 对象自带的三个方法,这三个方法的主要作用是改变函数中的 this 指向,从而可以达到接花移木的效果。本文将对这三个方法进行详细的讲解,并列出几个经典应用场景。 区分: 1、call(objec…

360浏览器设置多标签操作步骤

360浏览器设置多标签操作步骤 360浏览器怎么设置多标签?昨天小编写了一篇如何使用ie7浏览器设置多个主页的文章,就有小伙伴留言给小编360浏览器能否实现这项功能?当然有!下面小编就介绍操作方法: 1、打开360浏览器,在左上角找到“工具”点…

形参和实参是什么?? shim和polyfil是什么意思??

形参和实参是什么?? 实参(argument): 全称为"实际参数"是在调用时传递给函数的参数. 实参可以是常量、变量、表达式、函数等, 无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值…

占内存最小的浏览器:360安全浏览器超速版推荐

占内存最小的浏览器:360安全浏览器超速版推荐 占内存最小的浏览器有哪些?今天小编为大家推荐的是360安全浏览器超速版。本站提供360安全浏览器超速版最新正式版及抢票专版下载。那360安全浏览器超速版怎么样?看看小编整理的资料就清楚了。 360安全浏览器超速版资…

PS人像修图,通道磨皮、高低频磨皮、滤镜磨皮、人像精修

1、快速简单美肤-----高斯模糊磨皮: 原理 是高斯模糊蒙版。这种磨皮方法主要是针对面部的斑点及细纹。 操作流程概括:复制背景图层 》【滤镜】|【模糊】|【高斯模糊】命令 》 按‘Alt’键添加图层蒙版 》 在蒙版上使用画笔涂抹出想要模糊的地方》曲线…

java基础学习笔记(一)

java开发环境搭建:JDK配置 java 集成开发环境IDE(Integrated Development Environment) 》Eclipse工具 1、官网下载后安装elipse,注意:Eclipse 安装时JDK位数和Eclpise位数必须保持一致,安装过程中Switch…

谷歌浏览器怎么拦截网页广告 5步解决广告困扰

众所周知,广告是许多门户网站的主要收入来源之一,但广告内容的真实性辨识难度极高,一时大意便会中招。值得庆幸的是,许多浏览器产品都内置了广告拦截功能!下面小编就以谷歌浏览器为例,简单介绍一下广告拦截功能的开启方…

常用矢量图有哪些格式?AI文件存储为psd分层

前言 下载的矢量图资源会发现有ai格式、cdr格式的、eps格式、icon格式,有的能使用Photoshop打开而有的不行。使用Photoshop保存矢量图时候选择什么格式保存都是经常遇到的问题。 常见问题及解决:PS打开ai格式的矢量图文件,你用PS打开发现只…

来自天堂的连枷

来自天堂的连枷主要内容 《来自天堂的连枷》讲述的是:一个农夫将角长得越来越大的两头牛卖给屠户,他们商定的支付方式是,农夫给屠夫一配克油菜籽,然后由屠夫点数,一粒油菜籽付一块金币。途中农夫掉了一粒油菜籽&#…

百度地图API实现地图应用

企业官网上需要用到地图应用,这里对百度地图API的使用做点笔记,好记性不如烂笔头。 实现地图应用的流程如下: 1、获取密钥;教程网址 https://jingyan.baidu.com/article/363872eccda8286e4aa16f4e.html 2、在html的head头部引入…

win10开机密码忘记了的解锁教程

如今Win10系统逐渐成为了主流桌面系统,很多时候我们为了安全起见,往往会给自己的电脑系统设置一个开机密码,这样别人就不会轻易使用自己的电脑。但有时候难免会忘记开机密码。那么遇到Win10开机密码忘了怎么办呢?今天小编就给大家说说win10开…

java基础学习笔记(二)

1、数组排序之选择法排序和冒泡排序&#xff1f; 选择法排序原理&#xff1a;数组第一位和后续位置数值比较&#xff0c;最大或最小的调换位置后放在第一位&#xff1b;依次比较将第二大或小的值调换位置后放在第二位置&#xff1b;代码如下&#xff1a; for (int j 0; j <…

OneNote怎样显示或者隐藏网格线

网格线可添加到图表中以易于查看和计算数据的线条&#xff0c;能够辅助我们来对其图像或者是文本&#xff0c;很多新手用户在使用OneNote的时候不知道要怎样设置&#xff0c;下面小编就分享一下OneNote显示或者隐藏网格线的方法&#xff0c;还不知道的一起来学习一下OneNote显示…

java基础学习笔记(三)

1、装箱和拆箱 所有基本类型都有对应的类类型&#xff0c;比如int对应的类是Integer,这种类就叫做封装类。数字封装类有Byte、Short、Integer、Long、Float、Double这些类都是抽象类Number的子类。封装类和基本类型之间可以相互转换&#xff0c;而基本类型自动转封装类型就叫装…

win7如何设置还原点

win7系统是微软经典的操作系统&#xff0c;有很多比较实用的功能&#xff0c;比如说win7系统还原点的功能。通过win7设置还原点&#xff0c;可以把win7系统还原到还原点状态达到修复系统的目的。那么win7如何设置还原点?下面小编教下大家win7设置还原点的方法。 win7如何设置…

小鱼一键重装系统win7教程

最近有朋友想要自己安装win7操作系统&#xff0c;却不知道如何才能正确安装。于是就叫了电脑师傅来帮忙安装&#xff0c;又花了一点小钱。电脑师傅三下两除二就安装好&#xff0c;朋友询问下&#xff0c;电脑师傅才说出来这个一键安装win7的方法。下面就让我们一起来看看win7怎…

名片设计尺寸及注意事项(详尽),附加:文字转曲线或外框字;网址、文字转二维码方法

附加&#xff1a; 文字如何转曲线或外框字&#xff1f;&#xff1f; "转曲"是在用Corl Draw(简称CD)或者Adobe Illustrator(简称AI)做图时对文字作的一项重要操作,因为如果不转曲的话在把文件拿到其它电脑上编辑时可能会因为缺少字体文件而不能正常显示文字!! 转曲…

从域名注册到网站上线全过程(简单全面)

前言&#xff1a;刚开始是计划个人注册免费域名和免费的虚拟主机&#xff0c;目的是不花钱的完成到上线的全过程&#xff0c;点亮这个网站上线的技能树。后面公司需要做一个简单的展示性网站就名正言顺的进行尝试实现了。 个人总结&#xff1a;上线流程简单可以细分为以下几步…

win7纯净版镜像系统安装教程

虽然win10发布有很多长时间了&#xff0c;但是目前依然无法动摇win7在市面上的地位&#xff0c;有的小伙伴在买了预装win10系统的电脑用过之后还是想装回win7系统&#xff0c;下面就来看看win7纯净版镜像系统安装教程吧。 win7纯净版镜像系统安装教程 1、首先我们打开电脑浏览…