JS中的this
JS中的this
最近在学习JavaScript面向对象,其中有个难点就是关于this的问题。
关于this,我们要知道的两个问题,一个是this指向什么?另一个是this可以写在哪?
关于this的指向
总的来说,this指向对象,具体要分情况来说。
两个原则:
1、this的指向是运行时决定的;
2、在运行时,函数是谁调用的,this就指向谁。比如说:
在直接调用时,this指向window对象
func();//此时的this指向window对象
函数运行时被谁调用,this就指向谁
obj1.func(this);//此时的this指向obj1 obj2.func(this);//此时的this指向obj2
关于this可以写在哪里
this可以写在全局中或是函数中,下面来看这两种情况:
一、全局中
在全局中的this就指向window对象,例如:
var name = "foodoir";
this.name === window.name;//true

在全局中我们很容易将this的值和作用域弄混,其实this的值只与调用时函数所处的执行环境(execution context)相关,与函数作用域没有一点关系。
二、函数中
this在函数中的使用又可以分为几种情况
情况一:简单的函数
function f(){
var name = 'foodoir';
console.log(this.name);
}
f();//abc
情况二:在DOM事件中,事件监听中,this指向该元素本身
var element = document.getElementById('id');
element.onclick = function(){
console.log(this); //输出相应的元素自身 如input元素[object HTMLInputElement],指向DOM的元素
}
情况三:函数作为对象方法,当函数作为对象的方法时,this所指的即为包含该方法的那个对象。
var o = {
name:'foodoir',
say:function(){
console.log('hello ' + this.name);
}
}
o.say();//hello foodoir
情况四:构造函数情况,当this出现在构造函数中,this的值即为刚new好的那个对象。
function Person(name,age){
this.name = name;
this.age=age;
}
var p1 = new Person('foodoir',);
var p2 = new Person('jack',);
p1.name;//foodoir
p2.age;//

情况五:函数仅作为函数调用
在函数只是作为函数调用时,this值为全局变量window。下面这个例子定义了一个全局变量和全局函数,当函数直接调用时,this所指就是window对象;当函数作为对象的方法调用时,this指向o对象。此外,它也很好的解释了this的值只与执行上下文相关,而与函数本身或者说作用域是没有关系的。
//函数当做函数调用时,this指向全局变量window
var global = '我是全局变量';
function f(global){
alert(this.global);
}
f('test'); //输出'我是全局变量'
var o = {
f : f,
global : '对象中的变量'
}
o.f('test'); //输出'对象中的变量'

call和apply
可以使用call()和apply()方法改变函数的执行环境为指定对象的环境,则this所指的就是那个指定的对象。
call方法:
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
apply方法:
语法:apply([thisObj[,argArray]])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明:
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
直接看下面的例子:
function Animal(){
this.name = "Animal";
this.showName = function(){
console.log(this.name);
}
}
function Cat(){
this.name = "Cat";
}
var animal = new Animal();
var cat = new Cat();
animal.showName.call(cat,",");
animal.showName.apply(cat,[]);
//通过call或apply方法,将原本属于Animal对象的showName()方法交给对象cat来使用了。
//输出结果为"Cat"
call 的意思是把 animal 的方法放到cat上执行,原来cat是没有showName() 方法,现在是把animal 的showName()方法放到 cat上来执行,所以this.name 应该是 Cat
后面的话:
关于this,平时在遇到的时候,多想想几个问题:this出现在了哪?this指向什么?什么决定this的值?
感觉学面向对象有难度,看着例子好像是可以理解,但是实际不会用。每次想写点东西的时候,总觉得自己的思路是混乱的,不知道大家有没有什么好的方法推荐?欢迎大家在下面留言,文中有不对的地方也请指出来,在这里先谢谢了。
JS中的this的更多相关文章
- 5.0 JS中引用类型介绍
其实,在前面的"js的六大数据类型"文章中稍微说了一下引用类型.前面我们说到js中有六大数据类型(五种基本数据类型 + 一种引用类型).下面的章节中,我们将详细讲解引用类型. 1. ...
- 【repost】JS中的异常处理方法分享
我们在编写js过程中,难免会遇到一些代码错误问题,需要找出来,有些时候怕因为js问题导致用户体验差,这里给出一些解决方法 js容错语句,就是js出错也不提示错误(防止浏览器右下角有个黄色的三角符号,要 ...
- JS中给正则表达式加变量
前不久同事询问我js里面怎么给正则中添加变量的问题,遂写篇博客记录下. 一.字面量 其实当我们定义一个字符串,一个数组,一个对象等等的时候,我们习惯用字面量来定义,例如: var s = &quo ...
- js中几种实用的跨域方法原理详解(转)
今天研究js跨域问题的时候发现一篇好博,非常详细地讲解了js几种跨域方法的原理,特分享一下. 原博地址:http://www.cnblogs.com/2050/p/3191744.html 下面正文开 ...
- 关于js中的this
关于js中的this this是javascript中一个很特别的关键字,也是一种很复杂的机制,学习this的第一步就是要明白this既不指向函数自身也不指向函数的词法作用域,this实际上是函数被调 ...
- 表值函数与JS中split()的联系
在公司用云平台做开发就是麻烦 ,做了很多功能或者有些收获,都没办法写博客,结果回家了自己要把大脑里面记住的写出来. split()这个函数我们并不陌生,但是当前台有许多字段然后随意勾选后的这些参数传递 ...
- JS中 call() 与apply 方法
1.方法定义 call方法: 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 说明: call ...
- 在node.js中,使用基于ORM架构的Sequelize,操作mysql数据库之增删改查
Sequelize是一个基于promise的关系型数据库ORM框架,这个库完全采用JavaScript开发并且能够用在Node.JS环境中,易于使用,支持多SQL方言(dialect),.它当前支持M ...
- 分析js中的constructor 和prototype
在javascript的使用过程中,constructor 和prototype这两个概念是相当重要的,深入的理解这两个概念对理解js的一些核心概念非常的重要. 我们在定义函数的时候,函数定义的时候函 ...
- 如何在Node.js中合并两个复杂对象
通常情况下,在Node.js中我们可以通过underscore的extend或者lodash的merge来合并两个对象,但是对于像下面这种复杂的对象,要如何来应对呢? 例如我有以下两个object: ...
随机推荐
- Lisk沙箱漏洞分析及解决方案
背景 比特股的创始人Daniel Larimer质疑了lisk系统中的一系列问题,绝大多数都被lisk的创始人之一Max正面回应过了,具体可以看看这个http://ethereum.stackexch ...
- Windows和Linux都有的Copy-on-write技术
Windows和Linux都有的Copy-on-write技术 MySQL技术内幕Innodb存储引擎第2版 P375 SQL Server2008 实现与维护(MCTS教程)P199 LVM快照技术 ...
- Asp.Net Core 发布和部署( MacOS + Linux + Nginx )
前言 在上篇文章中,主要介绍了 Dotnet Core Run 命令,这篇文章主要是讲解如何在Linux中,对 Asp.Net Core 的程序进行发布和部署. 有关如何在 Jexus 中进行部署,请 ...
- RemoteIE 开发者可跨平台使用IE测试网页
RemoteIE,这是一个基于微软Azure的服务,它允许开发者在最新版本的IE(Windows 10技术预览版)中测试他们的网页,而不需要安装或在虚拟机中设置对应的系统.要想使用这项服务,开发者需要 ...
- ASP.NET Identity 2新增双重认证、帐号锁定、防伪印章功能并修复了一些bug
Microsoft最近发布了ASP.NET Identity 2,该版本支持双重认证.帐号锁定以及防伪印章功能,还增强了用户帐号和索引.此外新版本还包含一个改进的密码验证器并修复了一些bug. 借助于 ...
- 深圳电信光纤用户必备:简单破解中兴ZXA10 F460光电猫,实现WIFI和自动拨号功能
最近搬家,ADSL转成光纤宽带,下载速度非常给力.原来的ADSL路由器派不上用场,电信的安装人员也给开通了wifi功能,只是wifi无法上网,而且拨号一定需要用电脑连网线进行拨号.以前是直接把拨号账户 ...
- Linux环境下部署完JDK后运行一个简单的Java程序
前言 前一篇文章详细讲解了如何在Windows环境下安装虚拟机+Linux系统,并且成功部署了JDK. 不过部署完JDK之后,我们判断部署是否成功的依据是看"java -version&qu ...
- 剑指Offer面试题:27.最小的k个数
一.题目:最小的k个数 题目:输入n个整数,找出其中最小的k个数.例如输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 这道题是典型的TopK问题,其最简单的思路莫过于 ...
- ASP.Net WebForm温故知新学习笔记:一、aspx与服务器控件探秘
开篇:毫无疑问,ASP.Net WebForm是微软推出的一个跨时代的Web开发模式,它将WinForm开发模式的快捷便利的优点移植到了Web开发上,我们只要学会三步:拖控件→设属性→绑事件,便可以行 ...
- 学习scala03 控制结构
scala拥有非常宽松的控制结构. if与while scala中的if和while几乎和java中的结构一模一样. //if语句 val a= ){ println(“”) }else{ print ...