javascript知识整理之this
js中的this是一个头疼的问题,尤其对于笔者这种初级的菜鸟来讲,下面梳理下this的知识,可以当做是初级进阶也好入门也罢,总归输出的才是自己掌握的:
Js中this不是由词法作用域决定的 而是调用时动态指定,这就有点麻烦了,如果不能明确知道函数调用时的词法作用域this的指向也就只能靠猜了,算一卦这种模式不是不推荐而是根本不能用,要是真的不能确定this指向 可以查一下调用栈 或是上个断点之类的,当然alert这种较为原始的方法也是有效的不过确实有点low;
Js函数调用方式大致可以归为四类(此处是阮一峰大神总结的)即a.直接调用(默认指向)b.当方法调用(隐式指向)c.用new调用d.是特殊的调用方式(bind,call..)(显示指向);
当然了这里是有优先级的就像css的class一样 即: c > d > b > a;下面也说以便这四种当用方式(非严格模式):
A.直接调用
function fn(){
console.log(this)
}
fn();
这里的this是window 这个是比较简单基础,像是这样:
var n = 7;
function fn(){
this.n = 8;
function fn1(){
console.log(this.n)
}
return fn1();
}
var test = new fn();
这里this也是指向window的所以this.n==window.n 也就是7.这里也可以看出this不是基于词法作用域的 而是调用时指定的,怎么回事呢,有句话大概意思就是只要是函数声明其this都指向window ,与声明的位置无关;
B.当方法调用:
var name = "a";
var obj = {
name: "b",
sayname: function(){
console.log(this.name);
}
}
obj.sayname();
这个也是一个典型的基础的案例,输出 b ;this指向obj;这段代码其实就是这样的:
var name = "a";
var obj = new Object();
obj.name = "b";
obj.sayname = function(){
console.log(this.name);
}
obj.sayname();
这里有个小坑,像是这样:
var name = "a";
var obj = {
name: "b",
obj2: {
name: "c",
sayname: function(){
console.log(this.name);
}
}
}
obj.obj2.sayname();
Var test = obj.obj2.sayname;
Test();
第一个congsole是 c ;原因也是一直提的this不是取决于词法作用域的而是动态绑定的 obj.obj2.sayname 这里sayname是作为obj.obj2对象的函数调用的 所以this指向obj.obj2;
第二个console也好理解,当sayname赋值给变量test时当前执行上下文就变了。指向window了。所以第二个是c; 简单讲当方法调用时 this指向调用方法的那个对象;换言之谁调用了这个方法this指向谁;
C.由new调用:
先上代码:
var name = "b";
function fn(){
this.name = "a";
this.sayname = function(){
console.log(this.name)
}
}
var obj = new fn();
obj.sayname();
在看这段代码前应该了解下 new的时候到底发生了些什么事..,调用的时候由new调用的函数就是构造函数了.为什么用构造函数呢,这个也好理解,总不能相似的功能都要复制粘贴吧.以上边代码为例 当执行new fn()时 在fn函数第一行隐式的创建了一个对象即 var o = new Object();下面的this全部替换成了o,也就是o.name = “a”;... 最后把这个对象o return了。而又把这个返回值赋给了变量obj,obj的引用地址也是指向这个对象(复合类型);所以结果是a;
D.特殊的调用方式(有时候也叫硬性绑定或显示绑定):
Call与applay用法一样唯一区别在意一个传递的参数是集合(applay)另一个是用几个参数写几个参数(call):
var name = "a";
var obj = {
name: "b",
obj2: {
name: "c",
sayname: function(){
console.log(this.name);
}
}
}
obj.obj2.sayname.call(obj);
没错用了B 的例子,这下输出b ,我们给他硬性的绑定到了obj上,用apply与bind也是一样的; 还有像是eval setInterval等这种奇葩其作用域是全局的 要是在这里边用this不做处理的话都会指向window...
虽然this有点诡异却不是飘忽不定,哦对了 作为一个前端怎么不接触dom呢 dom事件也会改变this指向的比如:
document.onclick = function(){
console.log(this)
}
这里会打印document这个节点,简而言之事件在哪this就指向那;
javascript知识整理之this的更多相关文章
- Javascript语言精粹之正则表达式知识整理
Javascript语言精粹之正则表达式知识整理 1.正则表达式思维导图 2.正则表达式常用示例 2.1 移除所有标签,只留下innerText var html = "<p>& ...
- js事件(Event)知识整理
事件(Event)知识整理,本文由网上资料整理而来,需要的朋友可以参考下 鼠标事件 鼠标移动到目标元素上的那一刻,首先触发mouseover 之后如果光标继续在元素上移动,则不断触发mousemo ...
- Kali Linux渗透基础知识整理(二)漏洞扫描
Kali Linux渗透基础知识整理系列文章回顾 漏洞扫描 网络流量 Nmap Hping3 Nessus whatweb DirBuster joomscan WPScan 网络流量 网络流量就是网 ...
- js事件(Event)知识整理[转]
事件注册 平常我们绑定事件的时候用dom.onxxxx=function(){}的形式 这种方式是给元素的onxxxx属性赋值,只能绑定有一个处理句柄. 但很多时候我们需要绑定多个处理句柄到一个事件上 ...
- Kali Linux渗透基础知识整理(四):维持访问
Kali Linux渗透基础知识整理系列文章回顾 维持访问 在获得了目标系统的访问权之后,攻击者需要进一步维持这一访问权限.使用木马程序.后门程序和rootkit来达到这一目的.维持访问是一种艺术形式 ...
- wifi基础知识整理
转自 :http://blog.chinaunix.net/uid-9525959-id-3326047.html WIFI基本知识整理 这里对wifi的802.11协议中比较常见的知识做一个基本的总 ...
- 数据库知识整理<一>
关系型数据库知识整理: 一,关系型数据库管理系统简介: 1.1使用数据库的原因: 降低存储数据的冗余度 提高数据的一致性 可以建立数据库所遵循的标准 储存数据可以共享 便于维护数据的完整性 能够实现数 ...
- 【原文】前端程序员必须知道的高性能Javascript知识
原文:前端程序员必须知道的高性能Javascript知识 想必大家都知道,JavaScrip是全栈开发语言,浏览器,手机,服务器端都可以看到JS的身影. 本文会分享一些高效的JavaScript的最佳 ...
- 【转载】UML类图知识整理
原文:UML类图知识整理 UML类图 UML,进阶必备专业技能,看不懂UML就会看不懂那些优秀的资料. 这里简单整理 类之间的关系 泛化关系(generalization) 泛化(generalize ...
随机推荐
- Linux Shell 简介
什么是 Shell Shell 是用户和 Linux 内核之间的接口程序,当从 Shell 或其他程序向 Linux 传递命令时,内核会做出相应的反应: Shell 是一个命令语言解释器,它拥有自己内 ...
- 面试加分项---HashMap底层实现原理
想必大家都知道HashSet和HashMap之间的关系,HashSet是依赖于HashMap的,HashSet集合就是HashMap的key所组成的集合,我们都知道HashMap的value是可以重复 ...
- Python 学习图谱
https://mp.weixin.qq.com/s/-fJYAlOs4ui0YeJ-W6BkeQ
- Swagger使用
Swagger 1.集成springboot 第一步:pom <dependency> <groupId>io.springfox</groupId> <ar ...
- Django REST framework的分页
DRF分页组件 为什么要使用分页 我们数据表中可能会有成千上万条数据,当我们访问某张表的所有数据时,我们不太可能需要一次把所有的数据都展示出来,因为数据量很大,对服务端的内存压力比较大还有就是网络传输 ...
- swift 监测内存泄漏 MLeaksFinder
使用MLeaksFinder检测项目内存泄露总结 https://www.cnblogs.com/ocarol/p/5288497.html
- Solidity类型Uint类型区分?
1. Solidity中默认 Uint 也就是Uint256, 也就是 无符号 256位整数范围,即 2的 256次方 减一的 10进制范围, 预计大小为: 115792089237316195423 ...
- PHP开发——环境安装
PHP环境 Apache IDE的选择
- PHP开发——常量
概念 l 常量就是值永远不变的量.如:圆周率.身份证号码等. l 所谓常量值永远不变的量,是指在一次完整的HTTP请求过程中. l 常量在程序运行过程中,不能修改.也不能删除. l 常量比变量 ...
- javaweb开发.页面中文乱码问题
1.设置eclips , window->Preferences->web->JSP Files中的Encoding选项为UTF-8 2.修改jsp文件头部为UTF-8 <%@ ...