Javascript中的this该何去何从

Web前端 来源:Ziksang 67℃ 0评论

 在初阶段我看js中的时候简直就是一脸蒙B,跟现在的棒子国的女人一样,看来看去都是一个样,但是根本上还是不知道出自那个医生之手。

看完我这篇文章解析之后,你再到大街上蹲点去看看那些girl脸,那些是true or false,为了证实你真的看懂的js的this,你再去问问那些girl我说的是对的麻,但我不保证你不被打死。

本文规定  //=>  后面指的都是输出的结果


我们在游览器上先打印出最简单的this.看看是什么鬼

 


 

我在浏览器里console.log(this)     //打印出window{......}  打印出一个window对象

函数中执行时this的指向(1)最原始的函数调用

 


 

//=>window{.....}   此时输出的还是window对象,因为函数被调用的情况下为全局对象,所以this.指向的为window对象, 

函数中执行时this的指向(2)最原始的函数调用 ‘use strict'

//=>undefined  此时输出了一个underfined,在严格模式下此时对this.不会指向全局,而是全指向一个underfined ,以避免在写代码时出现一些莫名的情况,本来js就是一个不严谨的语言


 

作为一个对象字面量的方法调用时this的指向

 


 

//=>"ziksang"  此时输出一个字符串ziksang  此时的this指向的是obj对象,此时调用的this是根据运行时找到this的指向 ,指向的是obj对象,而obj对象下面有一个name为ziksang的属性,所以运行时候打印出的就是ziksang  

后面还要讲到一个定义时this指向的对象,所以我们一定要搞定运行时和定义时this的不同

彻底讲清this运行时指向的对象

 


 

//=>ziksang  根据前面的知识调用say()方法时我们一目了解的知道this.指向的是window对象,而window对象下面挂着一个name属性,所以调用this.name指向的是window下name的属性值,在这里我加了一个严格模式,如果不加'use strict',我不定义name属性则不会报错,因为变量提升的原因,加了之后 则会报一个

Uncaught TypeError: Cannot read property 'name' of undefined!!!意思说没有name这个属性 ,这些只是一个运行时指向的一个铺垫讲解,让我们去看看棒子mm到底怎么整成一个像一个娘养出来的

 


 

obj.say() //=> obj{}    此时obj.say()打印出来是一个obj对象,此时say方法里面的this.不是指向window对象麻 ?? 只是obj里面定义了一个say方法引用了say函数,说明一点此时say函数this是运行时才指向的,  指向了obj对象

obj2() //=>window{}对象  此时obj2()指向的是window对象 ,因为obj2是一个全局对象,挂在window下的,只是把obj.say对象的方法赋值给obj2变量,指行obj2() 指向的了window对象,这更说明了无论this定义时指向那里不是我们关心的,我们更关心,执行this时的运行环镜指向那里更为重要

再来一点恶心的东西,就是那些没牌没证的棒子医生,setTimeout里this的指向

 


 

理所当然的想法输出//=>ziksang

  obj.say() //=> 有军魂  突然一看又是一脸蒙B 前面还好好的this.name指向obj里的name属性,为什么加一个settimeout就变了呢??还是要说到this运行时指向的对象,因为setTimeout是window对象的方法,你造也造不出来,你改也改不掉!那此时this.name运行时理所当然的就指向了window对向下的name属性,我在全局对象上挂了一个name属性"有军魂"!所以最后打印出有军魂   

如何整治无证无牌上路的老司机,直接打掉黑作坊  用闭包改变this的指向

 


 

obj.say() //=> “ziksang”  我们改变了setTimeout运行时的指向,

在say方法里加一个局部作用域,把指向obj对象的this赋值给_this

,在setTimeout调用时直接改面其指向的window对向,硬改成obj对象,就能输出ziksang

宁愿被打脸也要说出事实,不向棒子妥协 ,别以为偷偷换脸就认不出你, this隐式改变   

 


 

test() //=> undefined  前面讲过在严格模式下 ,原生的调用函数this不会指向window对象,而是打印出一个undefined。

为什么?为什么?setTimeout执行 //=>输出 window对象  , 你服不服,反正我心里是不服,不是被啪啪打脸,不服也不行,直接看原因吧,因为setTimeout里面执行的匿名函数会隐式改变其this的指向,指向window。这一点大家一定要记在心里,脸不能被白打,吃一堑长一智!

构造函数里的this

 


 

构造函数和普通函数有什么区别?构造函数用new去实例化一个对象 !普通函数则是直接调用

new Ziksang() //=>打印出来是Ziksang{name:"ziksang",__proto__:"object"}  如果用new 构造出来的函数this指向这个构造器的本身 constructor指向Ziksang,本质上来说this和constructor指的是同一个地方

Ziksang()用函数调用的话 就像我们前面说的一样指的是window对象,严格模式下指的是undefined;

ECAMscript6就像中国的整容医生,这抄一点那抄一点就是全球第一  ECAM6中的this  箭头函数

 


 

在这这里面你看出来什么!看出来什么 ?

我擦输出肯定是//=》有军魂  

  我莫名的感觉脸又肿了起来,前面还指向window对象下的this  就变了一个写法就又变了,

前面讲的是运行时的环境,但如果用了es6那就是定义时的环境了。

正确输出 //=》ziksang  因为用了箭头函数时 ,this指向的是定义时的对向,此时定义在obj对象里,虽然运行时指向的是window对象,但是只要使用箭头函数就会指向定义时指向的对象,所以这里输出了ziksang  

 

装个B总结一下,打LOL去了



还有一个小细节当箭头函数运行时用call apply bind来改变其this指向也是TNN的不可能的,孩子别意想天开了,ES6就是想让Javascript的运行环境越来越规范,不要意想天开了孩子

写到这里我也累了,其实这个this还可以更深层次的讲,那就是用call apply bind来改变其this的指向,但作为我的想法就是一步一步来,之所谓深入了解,和解剖分析,就是让大家一步一步进入javascript的世界,真正知道javascript中的this改何去何从,实在憋不住LoL的诱惑了,你们谁改与我一战      黑色玫瑰  QQ494755899  外号ziksang  SOLO我能把你打的回家深入了解this

关闭

IT问道推荐

银行贷款频频被拒?
“Dr信用牛牛”让你远离信用污点 国内首家信用健康管理平台免费为你提供信用修复方案