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 ...
随机推荐
- Python爬虫中文小说网点查找小说并且保存到txt(含中文乱码处理方法)
从某些网站看小说的时候经常出现垃圾广告,一气之下写个爬虫,把小说链接抓取下来保存到txt,用requests_html全部搞定,代码简单,容易上手. 中间遇到最大的问题就是编码问题,第一抓取下来的小说 ...
- ligbox 插件介绍
浏览器支持情况:一般情况都支持.最好是jQuery v1.x + lightbox.js,这样的组合IE6,IE7,IE8也支持! 1 light插件的下载地址:https://pan.baidu.c ...
- [Ting's笔记Day5]在部署到Heroku之前,将Rails项目从SQLite设定为PostgreSQL
前情提要: Paas(平台及服务)公司Heroku是个可以把我们写好的App部署到网际网络的好地方.而本篇是我从自己的上一篇文章:将Ruby on Rails项目部署到Heroku遇到的问题,当时困扰 ...
- html 跳转页面传参、点击获取DOM参数
虽然现在前端框架已经很多,尤其是几大流行框架,比如Vue,React,Angular 等,已经去DOM化,但是还是有很多公司仍在使用 HTML + CSS + JS . 这里记载一下用到的HTML传参 ...
- container injection——容器技术
(一)容器技术为什么出现 在很久很久以前,想要在线上服务器部署一个应用,首先需要购买一个物理服务器,在服务器安装一个操作系统,然后安装好应用所需要的各种依赖环境,最后才可以进行应用的部署,而且一台服务 ...
- jeesite 下载ckfinder上传的文件
在需要下载的位置,将以下代码复制到页面最下方,就可以实现文件下载了 <script> $(document).ready(function() { var fileName = $(&qu ...
- PHP牛牛游戏算法
<?php namespace frontend\business; class NiuNiuGameHelper { /** * @param $card * @return int 结果 - ...
- [leetcode]57. Insert Interval插入区间
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessa ...
- Spark官方文档翻译(一)~Overview
Spark官方文档翻译,有问题请及时指正,谢谢. Overview页 http://spark.apache.org/docs/latest/index.html Spark概述 Apache Spa ...
- MAC系统上不能调试华为手机
调试问题: 使用MACOS会发现在android 开发环境完整的情况下,接入MOTO,SAMSUNG,HTC,ZTE等手机都可以自动识别,并可以在DDMS中查看LOGCAT,唯独华为的手机不可识别.U ...