js中我们常常会遇到this,this的具体指向问题对于很多同学来说是很懵懂的;就想lz刚开始接触时候就是一脸的懵逼,经常被一些题目转的眼花缭乱。那么今天lz就跟大家一起交流一下这个this的指向问题!

  背景:不久前有个同事给我们发了一道有关this的题目,于是便有了今天的故事。如下题:

class D0XX {
constructor () {
this.attr = {};
}
init (config) {
this.assign(config)
return this;
}
assign (config) {
this.attr.afterClose = config.afterClose;
}
close(){
if(typeof this.attr.afterClose === 'function'){
this.attr.afterClose();
}
}
}
class T0XX{
init(){
this.openPop()
}
openPop(){
new D0XX().init({
afterClose(){
console.log(this)
}
}).close()
}
}
new T0XX().init();
//請問打印出結果是什麼?

  一、且搁下此题目,我们先谈谈this的指向的以下几个情况;

  1.1.指向全局对象上;

    我们在一般的函数调用中的this是直接指向我们的全局对象的,比如:

function globalThis(){
console.log(this.name);//今天天氣真冷哇
}
var name = '今天天氣真冷哇'
globalThis(); setTimeout(function(){
console.log(this.name2);
},1000);
var name2 = '過了一秒鐘,我就更冷了'

    这里的setTimeout里面的this是指向window对象的!

  1.2.指向上文对象

    通俗点就是,哪个对象看上了我,我就跟谁,比如:

function foo() {
console.log(this.a);
}
var obj = {
a: '李四',
foo: foo
}
var a = '張三';
obj.foo(); //李四 看前面是哪个对象(obj),于是this跟obj一见钟情就好上了
var bar = obj.foo;
bar();//張三 你以为的以为。。 前面说过看对象,没对象,那就只能全局对象上茫茫人海只为寻她

  1.3.指向那个‘类’

    我们一般用构造函数进行调用时,会产生一个this始终是指向这个‘类’,我们复习下new 一个对象发生了什么: 

     1.创建一个全新的对象。

     2.这个对象会被执行[[Prototype]]连接。

     3.这个新对象会绑定到函数调用的this

     4.执行这个函数里的代码。

     5.如果函数没有返回其他对象,则自动返回这个新对象。

function fun() {
this.a = 1;
this.b = 2;
}
var instance = new fun();
console.log(instance.a);//

  1.4.箭头函数this指向当前作用域

    箭头函数this指向取决于外层的函数作用域或全局作用域,而且箭头函数的绑定无法修改,即使是new绑定也不可以。

document.onclick = ()=>{
console.log(this) //window
}
document.onclick=function(){
console.log(this) //document
}

  二、如何改变this的绑定关系

    2.1.显式绑定

    在此之前,相信你已经用过很多次applycall、bind函数了,使用这三个函数可以直接为你要执行的函数指定this,所以这种方式称为显式绑定。

function foo () {
console.log(this.a)
}
var obj = {
a: 2
}
foo.call(obj) // function foo (something) {
console.log(this.a, something)
return this.a + something
}
var obj = {
a: 2
}
var bar = foo.bind(obj); // bind返回一个绑定到obj上的新函数
var b = bar(3)
console.log(b)
var a = "window's a"
foo('!')

  如上就可以通过这种显式的方法进行改变绑定关系了;

  三、回归到之前同事的题目上

  通过以上的分析,我们就能够很清楚的分析出以上的答案是指向this.attr这个对象的,别看题目里又有new字符又有return this;这些东西,很容易让人迷糊;但是如果我们能掌握住this的这几种指向情况,相信会易容反掌的多;

  四、如果改动以上的题目你还知道么?

class D0XX {
constructor () {
this.attr = {}
}
init (config) {
this.assign(config)
return this
}
assign (config) {
this.afterClose = config.afterClose
}
close(){
if(typeof this.afterClose === 'function'){
this.afterClose()
}
}
}
class T0XX{
init(){
this.openPop()
}
openPop(){
new D0XX().init({
afterClose(){
console.log(this)
}
}).close()
}
}
new T0XX().init()
//請問打印出結果是什麼?

  最后,小Tip~就是之所以demo中可以使用链式调用是因为init方法中return出了this;这就跟jQuery中的链式调用有了异曲同工之妙;

  如有不妥,欢迎指教!

  

  

  

谈谈代码中的this的更多相关文章

  1. 谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持

    谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持 在本篇文章上一部分Order Processing的例 ...

  2. 简单谈谈js中的MVC

    MVC是什么? MVC是一种架构模式,它将应用抽象为3个部分:模型(数据).视图.控制器(分发器). 本文将用一个经典的例子todoList来展开(代码在最后). 一个事件发生的过程(通信单向流动): ...

  3. 谈谈JAVA中的安全发布

    谈谈JAVA中的安全发布 昨天看到一篇文章阐述技术类资料的"等级",看完之后很有共鸣.再加上最近在工作中越发觉得线程安全性的重要性和难以捉摸,又掏出了<Java并发编程实战& ...

  4. 谈谈CSS中一些比较"偏门"的小知识

    前面我写了:谈谈html中一些比较"偏门"的知识,现在这篇(主要)想谈谈个人所见的CSS一些小知识点,加深印象:同时也希望有需要的人能有收获! 1.常见的浏览器内核: 以IE为代表 ...

  5. 谈谈WPF中的CollectionView与CollectionViewSource (1)

    原文:谈谈WPF中的CollectionView与CollectionViewSource (1) 谈谈WPF中的CollectionView与CollectionViewSource (1)     ...

  6. 谈谈Integer中的静态类IntegerCache

            学习的本质就是一个赋值的过程,用新知识来覆盖你的旧知识或者无知(null).掌握知识是自己的, 分享知识,才能帮助更多的人,创造更大的价值.学贵以恒,以此自勉,与君共享.----曦阳X ...

  7. 谈谈javascript中的prototype与继承

    谈谈javascript中的prototype与继承 今天想谈谈javascript中的prototype. 通常来说,javascript中的对象就是一个指向prototype的指针和一个自身的属性 ...

  8. 移动端网站如何开发(电脑端网站到手机端网站我们需要在html代码中添加哪个meta标签)

    移动端网站如何开发(电脑端网站到手机端网站我们需要在html代码中添加哪个meta标签) 一.总结 一句话总结: 添加viewport标签:meta name="viewport" ...

  9. Python-Jenkins API使用 —— 在后端代码中操控Jenkins

    最近在工作中需要用到在后台代码中触发Jenkins任务的构建,于是想到Jenkins是否有一些已经封装好的API类库提供,用于处理跟Jenkins相关的操作.下面就简单介绍下我的发现. Linux C ...

随机推荐

  1. 一次多个数据库tnsping及登录单点登录需求

    [环境介绍] 系统环境:Linux + Oracle 11.2.0.4.0 + python 2.7.10 [背景描述] 需求:因为涉及生产数据库较多,业务夸多个数据库使用.当收到业务有些影响时,数据 ...

  2. 1.saltstack入门

    1.安装 master: yum install salt-master salt-minion -y minion: yum install salt-minion -y 2.修改配置文件(mini ...

  3. git bash 支持中文

      1. 编辑etc\gitconfig文件,在文件末尾增加以下内容: [gui] encoding = utf-8 #代码库统一使用utf-8 pathnameencoding = utf-8 #支 ...

  4. CAD快捷键

    F1: 获取帮助 F2: 实现作图窗和文本窗口的切换 F3: 控制是否实现对象自动捕捉 F4:数字化仪控制 F5: 等轴测平面切换 F6: 控制状态行上坐标的显示方式 F7: 栅格显示模式控制 F8: ...

  5. SAVEPOINT 标记

    create table duo(               --创建表格                v_xuhao number(3),                v_name varch ...

  6. iTOP-4418开发板所用核心板研发7寸/10.1寸安卓触控一体机

    iTOP-4418开发板所用核心板研发7寸/10.1寸安卓触控一体机 作为重中之重的电源管理选型,经多方对比测试最终选用AXP228,并得到原厂肯定 预留锂电池接口,内置充放电电路及电量计,可轻松搞定 ...

  7. 【vue】组件使用Deferred特性

    延迟加载组件 defer的意思是"延迟",所以deferred对象的含义就是"延迟"到未来某个点再执行. <template> <div> ...

  8. java笔试要点(java.sql包)

    提供JAVA存取数据库能力的包是 ( ) A: java.sql B: java.awt C: java.lang D: java.swing 解析: A,java.sql包提供Java存取数据库能力 ...

  9. pythonのdjango select_related 和 prefetch_related()

    在数据库有外键的时候,使用select_related() 和 prefetch_related() 可以很好的减少数据库请求次数,从而提高性能. (1)select_related()当执行它的查询 ...

  10. PyCharm的使用教程

    1.1 安装 首先去下载最新的pycharm ,进行安装.可以直接在官网下载. 1.2 首次使用 1,点击Create New Project. 2, 输入项目名.路径.选择python解释器.如果没 ...