this

this是js中的一个关键字,函数运行时自动生成的一个内部对象,只能在函数内部使用。我们要讨论的是 this 的指向。

this就是函数运行时自动生成的一个内部对象

下面介绍一下几种情况下,this的指向

1、全局环境

全局环境下,this就代表window对象。(针对web 应用来讲)

var name = 'zhar';
function say(){
console.log(this.name);//zhar
}
say();

同样,在 setTimeout 或 setInterval 这样的延时函数中调用也属于全局对象。

var name = 'zhar';
setTimeout(function(){
console.log(this.name);//zhar
},0);

2、对象环境

对象环境指向对象。

var obj = {
name : "zhar",
say : function(){
console.log(this.name);//zhar
}
}
obj.say();

下面举两个经典的例子:

var name = 'tom';
var obj = {
name : "zhar",
say : function(){
console.log(this.name);
}
}
var fun = obj.say;
fun();//输出 ?//tom-->fun定义在全局环境下,即window.fun()
//再次说明了this的指向是由运行时的执行环境来决定的
var name = 'tom';
var obj = {
name : "zhar",
say : function(){
return function(){
console.log(this.name);
}
}
}
obj.say()();//输出 ?//tom

3、构造函数环境

构造函数中的this 会指向创建出来的实例对象,使用new 调用构造函数时,会先创建出一个空对象,然后用call函数把构造函数中的this指针修改为指向这个空对象。执行完环境后,空对象也就有了相关的属性,然后将对象返回出去,所以说就不用我们自己手动返回啦~

function Person() {
this.name = 'zhar';
}
var p = new Person();
console.log(p.name);

综合以上,构造函数不需要返回值,如果我们指定一个返回值时,this的指向将发生变化

function Person() {
this.name = 'zhar';
return {};
}
var p = new Person();
console.log(p.name);//undefined
//--------------------------------------
function Person() {
this.name = 'zhar';
return {name:'tom'};
}
var p = new Person();
console.log(p.name);//tom 如果构造函数返回对象(Object,Array,Function),那 this 将指向这个对象,其它基础类型则不受影响
//--------------------------------------
function Person() {
this.name = 'zhar';
return 1;//number string boolean 等
}
var p = new Person();
console.log(p.name);//zhar

所以,如无必要我们通常不要设置构造函数的返回值

4、事件对象

在 DOM 事件中使用 this,this 指向了触发事件的 DOM 元素本身

li.onclick = function(){
console.log(this.innerHTML);
}

总结下来就是一句话:是谁调用的,this就指向谁

下面介绍一下如何来修改this 的指向

1、可以使用局部变量来代替this指针

var name = "zhar";
var obj = {
name : "zhar",
say : function(){
var _this = this;//使用一个变量指向 this
setTimeout(function(){
console.log(_this.name);
},0);
}
}
obj.say();

该方法为非常常用的一个方法

2、使用call 或 apply 方法

首先说明一下,call也是函数调用的一种形式,可以通过 函数名.call()来调用函数。但是提供了一个修改this指向的方法。

fun.call(thisObj[,arg1[,arg2[,...]]])

调用方式和传入参数如上面的形式。其中,所以call(thisObj[,arg1[,arg2[,...]]])中的第一个参数就是要更改this指向的对象,为必选参数; 之后的参数要根据调用的函数是否需要传入参数(为可选的)

下面通过代码来展示call 如何使用:

var name = 'zhar';
function say(){
console.log(this.name);
};
say();//zhar;
var obj = {
name : 'tom',
say : function(){
console.log(this.name);
}
}
say.call(obj);//tom 将 say 函数中的 this 替换为传入的对象
obj.say();//tom
obj.say.call(null);//zhar 将 obj.say 函数的 this 替换为了 null,也就意味着指向了全局环境
//前面课程的继承代码
function Person(){
this.name = "人";
}
function Student(){
Person.call(this,null);
}
var s = new Student();
console.log(s.name);
li.onclick = function(){
console.log(this.innerHTML);//此处的 this 代表着 DOM 元素
function update(){
this.innerHTML += " new ";
}
//update();//这样做的话,this 的指向将变为window
update.call(this);//通过 call 方法修改函数内 this 的指向
}
//call 的传参
function say(arg1,arg2){
console.log(this.name,arg1,arg2);
};
var obj = {
name : 'tom',
say : function(){
console.log(this.name);
}
}
say.call(obj,'one','two');//tom one two

apply

apply的作用和call一样,不同的是传参的形式。apply需要以数组的形式传递参数

//apply 的传参
function say(arg1,arg2){
console.log(this.name,arg1,arg2);
};
var obj = {
name : 'tom',
say : function(){
console.log(this.name);
}
}
say.apply(obj,['one','two']);//tom one two

以上就是关于this指向和如何修改this指向的介绍

点击查看原文

JS中----this的指向和如何修改this的指向的更多相关文章

  1. JS中OOP之模拟封装和继承和this指向详解

    大家好,今天我带大家学习一下js的OOP, 大家都知道,面向对象有三个基本特征,继承,封装和多态,面向对象的语言有那么几种,C++,PHP,JAVA等,而功能强大的JS可以模拟实现面向对象的两大特征, ...

  2. js中的几种继承方法

    JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一. 继承:子承父业:一个原本没有某些方法或属性的对象,统一写方法,拿到了另外一个对象的属性和方法 下面是js中的几种继承方式 1.改变this ...

  3. js中修改this指向的方法(call,apply,bind)

    前言:call.apply和bind都是为了改变某个函数运行时的this指向的,对于前端人员来说,关于this的掌握程度,直接决定了前端水平的高低.下面我们就来简单浅显易懂的来看一下es5中常用的三种 ...

  4. 关于js中this指向的理解总结!

    关于js中this指向的理解! this是什么?定义:this是包含它的函数作为方法被调用时所属的对象. 首先,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁 ...

  5. js 中this到底指向哪里?

    其实js的this指向很简单.我们记住下面3种情况. this 指向的是浏览器中的window.代码如下: function fn(){ this.name='yangkun'; this.age=2 ...

  6. js中this绑定方式及如何改变this指向

    this的绑定方式基本有以下几种: 隐式绑定 显式绑定 new 绑定 window 绑定 箭头函数绑定 隐式绑定 第一个也是最常见的规则称为 隐式绑定. var a = { str: 'hello', ...

  7. JS中this指向的更改

    JS中this指向的更改 JavaScript 中 this 的指向问题 前面已经总结过,但在实际开中, 很多场景都需要改变 this 的指向. 现在我们讨论更改 this 指向的问题. call更改 ...

  8. js中this指向的问题与联系

    前言 JavaScript 中最大的一个安全问题,也是最令人困惑的一个问题,就是在某些情况下this的值是如何确定的.有js基础的同学面对这个问题基本可以想到:this的指向和函数调用的方式相关.这当 ...

  9. 彻底理解js中this的指向,不必硬背。

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...

随机推荐

  1. 【页面加载】【九九乘法表】【document.write的功能_】【<script>直接显示数组】【声明新变量】

    1.页面加载时向body加载文本.弹出框 <body>        <script>            document.write("<h1>Ja ...

  2. IMAGENT CLASSIFICATION WITH DEEP CONVOLUTIONAL NEURAL NETWORKS(翻译)

    0 - 摘要  我们训练了一个大型的.深度卷积神经网络用来将ImageNet LSVRC-2010竞赛中的120万高分辨率的图像分为1000个不同的类别.在测试集上,我们在top-1和top-5上的错 ...

  3. Linux 逻辑卷管理LVM

    LVM概述 Logical Volume Manager,逻辑卷管理 屏蔽了底层磁盘布局,便于动态调整磁盘容量 需要注意:/boot分区用于存放引导文件,不能应用LVM机制 LVM结构 目标:将sdb ...

  4. 修复服务器上出现ImportError: cannot import name main的问题

    在服务器上成功升级pip2之后再运行pip2命令出现如下报错信息 Traceback (most recent call last): File "/usr/bin/pip2.7" ...

  5. oracle查看未提交事务

    SELECT s.sid, s.serial#, s.event, a.sql_text, a.sql_fulltext, s.username, s.status, s.machine, s.ter ...

  6. (ScrollViewer或者有滚动条的控件)嵌套一个(ScrollViewer或者有滚动条的控件)禁用里面的滚动条

    转自:http://blog.csdn.net/haylhf/article/details/8351203 后有改动 在C# 中,两个ScrollViewer嵌套在一起或者ScrollViewer里 ...

  7. gitlab的配置

    一. 管理员配置 gitlab 1. 登录 gitlab 等待 docker 容器启动完成后, 登陆 http://localhost:8080 第一次访问是让我们修改管理员密码.如下所示 初始化 g ...

  8. 20165231 2017-2018-2 《Java程序设计》第7周学习总结

    教材学习内容总结 第十一章 MySQL数据库管理系统,简称MySQL,是世界上最流行的开源数据库管理系统,其社区版(MySQL Community Edition)是最流行的免费下载的开源数据库管理系 ...

  9. cocosCreater开发时遇到的问题

    生成vscode任务后无法编译: ctrl +p  -> 输入task compile 编译任务时提示 :由于使用任务版本 0.1.0,以下工作区文件夹将被忽略 这是cocos默认生成的code ...

  10. 缓存系列之三:redis安装及基本数据类型命令使用

    一:Redis是一个开源的key-value存储系统.与Memcached类似,Redis将大部分数据存储在内存中,支持的数据类型包括:字符串.哈希表.链表.集合.有序集合以及基于这些数据类型的相关操 ...