JavaScript中的this
本文尽量避免概念性的讲解,那样太抽象
所以下面以一些简单的例子,从易到难对this的用法总结
1.方法中的this会指向当前执行该方法的对象 如:
var name = "window"
var Tom = {
name:"Tom";
show:function(){
console.log(this+":"+this.name)
}
} Tom.show(); //Tom
2.方法中的this不会指向声明它的对象 如下
var Bob={
name:"Bob",
show:function(){
console.log(this+":"+this.name)
}
};
var Tom={
name:"Tom",
show:Bob.show
};
Tom.show() ; //Tom
尽管console.log是Bob对象环境中声明的 ,但方法是由Tom对象调用执行
所以this总是会指向当前执行的对象,而不是声明的对象
其本质原因是:Bob.show方法赋值给Tom.show方法的时候不会把Bob对象也给绑定过去
下面是个将对象绑定过去的例子
3.嵌套对象中,this指向直接绑定它的对象
var Bob={
name:"Bob",
Tom:{
name:"Tom",
show:function(){console.log(this+":"+this.name)}
}
}
Bob.Tom.show(); //Tom
4.用变量保存方法的执行结果,其执行对象仍然是Tom
var name="window";
var Tom={
name:"Tom",
show:function(){
console.log(this+":"+this.name)
}
}; var fun=Tom.show();
fun(); //Tom
此处fun所赋值的是Tom.show函数执行的结果,也就是Tom
上面的例子其实是下面所做对照的
5.用变量保存方法的内容,其执行对象是window
var name="window";
var Tom={
name:"Tom",
show:function(){
console.log(this+":"+this.name)
}
}; fun=Tom.show;
fun(); //Window
因为fun赋值的只是方法的内容,并没有绑定在Tom对象上,所以fun执行对象是window对象
6.若指明了调用方法的对象的话,this会指向调用其的对象 如下:
var name = "window";
var Bob= {
name:"Bob",
show:function(){console.log(this.name);}
}; var Tom= {name: "Tom"};
Bob.show(); //Bob
Bob.show.apply(); //window
Bob.show.apply(Tom); //Tom
当然call()也差不多类似,apply和call用于指明由哪个对象去执行该方法
7.函数作为构造器时,this会指向新建的对象,如下
function Tom(name,age){
this.name=name;
this.age=age;
this.getInfo=function(){
console.log(this.name+" is "+this.age)
}
}
var Bob = new Tom("Bob",45);
Bob.getInfo(); //Bob is 45
我们来点进阶的东西!!!
下面例子要解释的通 则需要两个重要的概念
延迟执行!
延迟调用!
8.将对象赋值给变量后,再调用方法,执行的对象仍然是Tom
var name="window";
var Tom={
name:"Tom",
show:function(){console.log(this.name)},
wait:function(){
var that=this;
that.show();
}
}; Tom.wait(); //Tom
因为show绑定在that的对象里,而that的值是对象Tom,所以执行的对象指向了Tom
"将对象保存到变量,再去调用方法",这个过程称为延迟调用,若不明白没关系
接着往下看
9.在函数上下文中若没有指明执行方法的对象,那么会由全局对象window来执行
var name="window";
var Tom={
name:"Tom",
show:function(){console.log(this.name)},
wait:function(){
var fun=this.show;
fun();
}
}; Tom.wait(); //window
fun赋值的是方法的内容,没有绑定于Tom对象里,因此执行的对象是window
上面的"把方法赋值给变量,再调用"这个过程可以看做延迟执行
延迟执行方法会导致该方法失去对象的绑定,导致对象由window执行执行
下面是一些延迟调用的例子
10.匿名函数的延迟
var name="window";
var Tom={
name:"Tom",
show:function(){console.log(this.name)},
wait:function(){!function(call){call();}(this.show)}
} Tom.wait(); //Window
11.setTimeout、setInterval函数延迟
这里只以setTimeout为例子
var name="window";
var Tom={
name:"Tom",
show:function(){console.log(this.name)},
wait:function(){setTimeout(this.show,1000)}
} Tom.wait(); //window
从上面两个例子可以得出:延迟执行会使得执行方法的对象更改为全局对象window
那么如何防止这种更改呢,我们尝试下面一招
12. 在延迟的环境下 尝试让Tom加班(对象也跟着延迟)
var name="window";
var Tom={
name:"Tom",
show:function(){console.log(this.name)},
wait:function(){setTimeout(Tom.show,1000)}
} Tom.wait(); //window
上面中this就直接指明Tom,尝试让Tom加班,但是结果仍然为Window对象
因为Tom.show放在第一个参数里,就相当于这个方法被保存到一个变量里
然后经过延迟后再执行这个变量,而保存的时候依然没有绑定到对象Tom,因此执行的对象依然是window
这个和上面第9个例子是一个道理的。称为延迟执行,只不过这次的延迟执行是用了setTimeout来实现
那么难道没有办法避免延迟执行方法导致执行对象被更改了吗?非也!
让对象也跟着延迟就可以做到!如下
13.虽然延迟会导致方法的执行对象被更改为Window 但也有办法防止执行对象更改 如下
var name="window"
var Tom ={
name : "Tom",
show : function(){console.log(this.name);},
wait: function(){
var that=this;
setTimeout(function(){that.show()},1000)}
} Tom.wait(); //Tom
通过变量保存对象,再使用变量去调用方法,达到执行的对象也跟着延迟的效果
14.eval函数的延迟
对于eval比较特殊
在eval环境下,执行的对象就是当前作用域的对象 如下
var name="window";
var Bob={
name:"Bob",
showName: function(){ eval("console.log(this.name)"); }
}; Bob.showName(); //Bob
15.eval函数的环境下,不会受到延迟而影响函数执行的对象
之所以eval特殊是因为eval不受延迟的影响
var name="window";
var that;
var Tom={
name:"Tom",
show:function(){console.log(this.name)},
wait:function(){that=this;setTimeout("that.show()",1000)}
} Tom.wait(); //Tom
也许你会觉得上面的代码没有eval函数的身影
其实setTimeout函数的第一个参数就是eval环境
他会指向当前执行作用域的执行对象,忽略延迟方法延迟调用
点击下面可以看看田小计划对JavaScript的this是如何见解
http://www.cnblogs.com/wilber2013/p/4909505.html
能把上面例子都理解了,那么this是一把有利的刀!
当然如果不能理解,那么像闭包一样 尽量的少用!
JavaScript中的this的更多相关文章
- javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈
Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...
- javascript中的this与函数讲解
前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...
- JavaScript 中的数据类型
Javascript中的数据类型有以下几种情况: 基本类型:string,number,boolean 特殊类型:undefined,null 引用类型:Object,Function,Date,Ar ...
- javascript中的操作符详解1
好久没有写点什么了,根据博主的技术,仍然写一点javascript新手入门文章,接下来我们一起来探讨javascript的操作符. 一.前言 javascript中有许多操作符,但是许多初学者并不理解 ...
- 掌握javascript中的最基础数据结构-----数组
这是一篇<数据结构与算法javascript描述>的读书笔记.主要梳理了关于数组的知识.部分内容及源码来自原作. 书中第一章介绍了如何配置javascript运行环境:javascript ...
- javascript中变量提升的理解
网上找了两个经典的例子 var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); // 10 var ...
- 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型
前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...
- 简单分析JavaScript中的面向对象
初学JavaScript的时候有人会认为JavaScript不是一门面向对象的语言,因为JS是没有类的概念的,但是这并不代表JavaScript没有对象的存在,而且JavaScript也提供了其它的方 ...
- Javascript中的valueOf与toString
基本上,javascript中所有数据类型都拥有valueOf和toString这两个方法,null除外.它们俩解决javascript值运算与显示的问题,本文将详细介绍,有需要的朋友可以参考下. t ...
- 关于javascript中的this关键字
this是非常强大的一个关键字,但是如果你不了解它,可能很难正确的使用它. 下面我解释一下如果在事件处理中使用this. 首先我们讨论一下下面这个函数中的this关联到什么. function doS ...
随机推荐
- 使用redis构建可靠分布式锁
关于分布式锁的概念,具体实现方式,直接参阅下面两个帖子,这里就不多介绍了. 分布式锁的多种实现方式 分布式锁总结 对于分布式锁的几种实现方式的优劣,这里再列举下 1. 数据库实现方式 优点:易理解 缺 ...
- Security Policy:行级安全(Row-Level Security)
行级安全RLS(Row-Level Security)是在数据行级别上控制用户的访问,控制用户只能访问数据库表的特定数据行.断言是逻辑表达式,在SQL Server 2016中,RLS是基于安全断言( ...
- EditText 基本用法
title: EditText 基本用法 tags: EditText,编辑框,输入框 --- EditText介绍: EditText 在开发中也是经常用到的控件,也是一个比较必要的组件,可以说它是 ...
- 读python源码--对象模型
学python的人都知道,python中一切皆是对象,如class生成的对象是对象,class本身也是对象,int是对象,str是对象,dict是对象....所以,我很好奇,python是怎样实现这些 ...
- zookeeper源码分析之一服务端启动过程
zookeeper简介 zookeeper是为分布式应用提供分布式协作服务的开源软件.它提供了一组简单的原子操作,分布式应用可以基于这些原子操作来实现更高层次的同步服务,配置维护,组管理和命名.zoo ...
- 马里奥AI实现方式探索 ——神经网络+增强学习
[TOC] 马里奥AI实现方式探索 --神经网络+增强学习 儿时我们都曾有过一个经典游戏的体验,就是马里奥(顶蘑菇^v^),这次里约奥运会闭幕式,日本作为2020年东京奥运会的东道主,安倍最后也已经典 ...
- Axure 8.0.0.3312可用注册码
用户名:aaa 注册码:2GQrt5XHYY7SBK/4b22Gm4Dh8alaR0/0k3gEN5h7FkVPIn8oG3uphlOeytIajxGU 用户名:axureuser 序列号:8wFfI ...
- Could not evaluate expression
VS15 调试变量不能显示值,提示:Could not evaluate expression 解决办法: 选择"在调试时显示运行以单击编辑器中的按钮"重启VS即可. 可参考:Vi ...
- bzoj1079--记忆化搜索
题目大意:有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块.所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个木块涂相同色显得 ...
- 28个你必须知道的HTML5的新特性,技巧以及技术
崭新新的页面布局 传统的: HTML5: 1. 新的Doctype 尽管使用<!DOCTYPE html>,即使浏览器不懂这句话也会按照标准模式去渲染 2. Figure元素 用<f ...