博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
this指向问题
阅读量:7197 次
发布时间:2019-06-29

本文共 3211 字,大约阅读时间需要 10 分钟。

导语

首先,如果搜索:js中this的指向问题

必然会得到这个结论:this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定,this最终指向调用它的对象。

但是发现有时候只依靠这句话还是会在判断this指向的时候出现问题。今天通过几个例子彻底搞懂this指向问题。

例子1

function flora(){    var Animal = "?";    console.log(this.Animal); //undefined    console.log(this); //Window}flora();复制代码

实际上,这里调用flora();是由window对象调用的,把flora();改成window.flora();控制台打印的同样是Window。

例子2

var flora = {    Animal:"?",    say:function(){        console.log(this.Animal);  //?    }}flora.say();复制代码

this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定,这里flora调用了say,所以this指向对象flora

例子3-1

var flora = {    Animal:"?",    say:function(){        console.log(this.Animal);  //?    }}window.flora.say();复制代码

例子3-2

var flora = {    Animal:"?",    mars:{        Animal:"?",        say:function(){             console.log(this.Animal);  //?    	}    }}flora.mars.say();复制代码

例子3-1的this竟然没有指向window,例子3-2的this竟然没有指向flora,不是说this最终指向调用他的对象吗?!! 结论竟然失效了,其实也不是,对于这种多层调用的情况

一个含有this的函数不管被多少花里胡哨的对象调用,this也只是指向它上一级的对象

例子4

var flora = {    Animal:"?",    mars:{        Animal:"?",        say:function(){             console.log(this);   //window            console.log(this.Animal);  //undefined    	}    }}var pink = flora.mars.say;pink();复制代码

…fá生了什么,this怎么指向了window? 别急,想想我们的理论:this最终指向调用它的对象;

什么时候调用了它?是不是pink()的时候,这个跟上面的?不一样,上面的例子直接执行了say;

没有哪一句话可以让我们直接判断this指向,分析的时候小心一点就可以啦(⁎⁍̴̛ᴗ⁍̴̛⁎)

例子5-1

function flora(){    this.animal = "?";}var blue = new flora();console.log(blue.animal); //?复制代码

这里blue对象之所以可以打印出函数flora里面的animal是因为new可以改变this的指向

其实可以这么理解,我们在var blue = new flora();的时候,复制了一个florablue里面

注意⚠️这个时候并没有执行,而调用的时候是blue对象,所以this指向的就是blue

为什么blueanimal属性,因为flora已经复制到了blue对象中。

如果构造函数有返回值呢?⬇️

例子5-2

function flora(){    this.animal = "?";       return {}}var blue = new flora();console.log(blue.animal); //undefinedfunction flora(){    this.animal = "?";       return function(){};}var blue = new flora();console.log(blue.animal); //undefined复制代码

返回的是一个对象,this指向的就是那个返回的对象;

例子5-3

function flora(){    this.animal = "?";       return 1;}var blue = new flora();console.log(blue.animal); //?function flora(){    this.animal = "?";       return undefined;}var blue = new flora();console.log(blue.animal); //?复制代码

如果返回的不是对象,this还是指向这个函数的实例

例子5-4

function flora(){    this.animal = "?";       return null}var blue = new flora();console.log(blue.animal); //?复制代码

比较特别的是:虽然null属于对象,但是返回null依然指向函数实例

Null类型只有一个值的数据类型,这个特殊值是null。从逻辑角度来看,null值表示一个空对象指针,这也是使用typeof操作符检测null值时会返回"object"的原因

补充

  1. 箭头函数:箭头函数本身是没有this,但我们用到this的时候,他会找定义函数时所处环境的this.
  2. 在严格模式下,默认的this不是window,是undefined。(使用了"user strict"启用严格模式)
  3. new之所以可以改变this的指向,跟apply有关,还有其他方法可以改变this指向,后续文章会提到

给大家做两道测试题吧!?

测试题

测试题1

var animal = '?'; function flora() {    var animal = '?';    console.log(this.animal); } window.flora();   var obj = {    animal: '?',    say: function() {        console.log(this.animal);    } } obj.say();   var mrz = obj.say; window. mrz();复制代码

答案:? ? ?

测试题2

var animal = '?'; (function() {    var animal = '?';    console.log(this.animal); })()  function flora() {    var animal = '?';    function mrz() {        console.log(this.animal);    }    mrz();  } flora();复制代码

答案:? ?

  1. 因为匿名函数没有名字,所以就挂给window
  2. 谁调用mrz那么就指向谁,它不是window调用的,也不是flora调用的,没有人管它,那么它就指向window,无主函数

转载于:https://juejin.im/post/5cf395bbe51d455a2f220216

你可能感兴趣的文章
【设计模式】外观模式
查看>>
Flume的各种类型的组件介绍
查看>>
Metro Style App开发快速入门 之基本控件使用总结
查看>>
关于ios通话应用退到后台语音中断处理办法
查看>>
10.5 搜索的优化版
查看>>
memcached 使用(perl)
查看>>
Pimpl常用法
查看>>
WPF Step By Step 控件介绍
查看>>
redis采用tcmalloc导致无法释放内存的问题
查看>>
iOS开发视频教程下载/iphone开发视频教程下载
查看>>
Makefile,如何传递宏定义DEBUG【转】
查看>>
android HDMI (一):HDMI基础篇【转】
查看>>
jQuery的DOM操作
查看>>
使用Docker安装软件
查看>>
form_checkbox: Example code of Early Access iText
查看>>
Asp.net控件开发学习笔记(十二)----数据绑定
查看>>
关于.NET解决方案批生成的一点探索(同一个解决方案下多项目批生成)
查看>>
【jquery模仿net控件】简单的datalist控件更新,及其简单应用
查看>>
SQL SELECT INTO 语句使用问题
查看>>
设计模式:Strategy 策略模式 -- 行为型
查看>>