范文健康探索娱乐情感热点
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

js中this指向的问题与联系深入探究

  1.0 前言
  JavaScript 中最大的一个安全问题,也是最令人困惑的一个问题,就是在某些情况下this  的值是如何确定的。有js基础的同学面对这个问题基本可以想到:this  的指向和函数调用的方式相关。这当然是正确的,然而,这几种方式有什么联系吗?这是我接下来要说明的问题。
  2.0 this从哪里来
  this   是js的一个关键字,和arguments  类似,它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用。这句话似乎与认知不同,我们在函数体外部即全局作用域下也能使用this  。// 直接在全局作用域下输出this console.log(this); // 输出window
  但是不要忘记,即便是全局作用域,依旧是运行在window  下的,我们写的代码都在window  的某个函数中。而这也催生了一种理解this  指向的方法:this  永远指向调用者(非箭头函数中)。
  3.0 作为普通函数调用
  函数作为普通函数直接调用(也称为自执行函数)的时候,无论函数在全局还是在另一个函数中,this  都是指向window  。function fn() { this.author = "Wango"; }  fn(); console.log(author); // Wango
  这很好理解,但又不是很好理解,因为在代码中省略了window  ,补全后就好理解了:this  指向的是调用者。
  function fn() { this.author = "Wango"; }  window.fn(); console.log(window.author); // Wango
  而在内部函数中,自执行函数中的this  依旧指向全局作用域,我们 无法通过window.foo()  调用函数,但并不妨碍我们先这样理解(具体参见本文最后一部分this  的强制转型) 。
  function fn() { function foo() { console.log(this); } foo(); // Window window.foo(); // TypeError }  fn();
  4.0 作为构造函数调用
  在构造函数中,this  指向new  生成的新对象,即构造函数是通过new  调用的,构造函数内部的this  当然就应该指向new  出来的对象。
  function Person(name, age) { this.name = name; this.age = age; console.log(this); // Person { name: "Wango", age: 24 } }  new Person("Wango", 24);  构造函数中的this与构造函数的返回值类型无关,下列代码中p指向了构造函数返回的对象,而不是new出来的对象。当然,这是构造函数的特性,与本主题关系不大。
  function Person(name, age) { console.log(this); // Person {} this.name = name; this.age = age; console.log(this); // Person { name: "Wango", age: 24 }  return { name: "Lily", age: 25 } }  Person.prototype.sayName = function() { return this.name + " " + this.age }  const p = new Person("Wango", 24); console.log(p.sayName()); // TypeError: p.sayName is not a function  5.0 作为对象方法调用
  通过对象方法调用时,this  指向应该是最明晰的了。与其他面向对象语言的this  行为相同,指向该方法的调用者。
  function Person(name, age) { this.name = name; this.age = age; }  Person.prototype.sayName = fn;  function fn() { return this.name + " " + this.age }  const p = new Person("Wango", 24); console.log(p); // Person { name: "Wango", age: 24 } console.log(p.sayName()); // Wango 24
  5.1 通过【】调用对象方法
  通常,我们对于对象方法是通过.  语法调用,但通过[]  也可以调用对象方法,在这种情况下的this  指向常常会被我们混淆、忽略。
  function fn() { console.log(this); }  const arr = [fn, 1];  arr[0](); // [Function: fn, 1]  function fn2() { arguments[0](); }  fn2(fn, 1); // [Arguments] { "0": [Function: fn], "1": 1 }
  在上例中,无论是数组还是伪数组,其本质上都是对象,在通过 []  获取函数元素并调用的时候,会改变函数中的this  指向,this  指向这个数组或伪数组,与对象调用函数的行为一致。
  6.0  通过call、apply调用function fn() { console.log(this.name); }  const author = { name: "Wango" }  fn.call(author); // Wango
  这似乎与this  永远指向调用者相违背,但一旦我们明白了call函数的实现机制就会明白,这不仅不是违背,反而是佐证。对call  、apply  、bind   下面截取call  简要说明。
  // 保存一个全局变量作为默认值 const root = this;  Function.prototype.myCall = function(context, ...args) { if (typeof context === "object") { // 如果参数是null,使用全局变量 context = context || root; } else { // 参数不是对象的创建一个空对象 context = Object.create(null); } // 使用Symbol创建唯一值作为函数名 let fn = Symbol(); context[fn] = this; context[fn](...args); delete context[fn]; }
  call   函数最核心的实现在于context[fn] = this;  和context[fn](...args);  这两行。实际上就是将没有函数调用者的普通函数挂载到指定的对象上,这时this  指向与对象调用方法的一致。而delete context[fn];  是在调用后立即解除对象与函数之间的关联。
  7.0 严格模式下的不同表现
  7.1 this强制转型
  使用函数的apply()  或call()  方法时,在非严格模式下null  或undefined  值会被强制转型为全局对象。在严格模式下,则始终以指定值作为函数this  的值,无论指定的是什么值。这也是为何在严格模式下,自执行函数的this  不再指向window  ,而是指向undefined  的根本原因。
  // 定义一个全局变量 color = "red"; function displayColor() { console.log(this.color); } // 在非严格模式下使用call修改this指向,并指定null,或undefined, displayColor.call(null); displayColor.call(); // red
  // 修改指向无效,传入null或undefined被转换为了window
  实际上,我们也可以将自执行函数,如fn()  ,看作是fn.call()  的语法糖,在普通模式下,第一个参数默认为undefined  ,但被强制转换为window  。这也就解释了为何所有自执行函数中this  都指向window  但无法通过window  调用的问题(函数在call  函数中挂载到window  对象上,执行后被立即删除,所以无法再次通过window  访问)。
  apply()   或call()  方法在严格模式下传入简单数据类型作为第一个参数时,该简单数据类型会被转换为相应的包装类,而非严格模式不会如此转换。function foo() { console.log(this); }  foo.call(); // Window {} foo.call(2); // Number {2}   function foo() { console.log(this); }  foo.call(); // undefined foo.call(2); // 2
  8.0 箭头函数的this指向
  在箭头函数中, this  引用的是定义箭头函数的上下文。即箭头函数中的this   不会随着函数调用方式的改变而改变。
  function Person(name) { this.name = name;  this.getName = () => console.log(this.name); }  const p = new Person("Wango");  p.getName(); // Wango  const getName = p.getName;  getName(); // Wango getName.call({name: "Lily"}); // Wango

轻松打造家庭影院!只需一部投影就能轻松在家体验影院级享受在人们对于影音娱乐需求日益增长的今天,投影仪凭借着小空间投出大尺寸的优势,开始受到更多家庭的青睐,而随着投影市场的日益火爆,面对市面上品牌繁多的投影仪,很多小白用户犯了难不知道该如诋毁码链及扫一扫技术专利侵犯权利人名誉被判公开赔礼道歉日前,上海市浦东新区人民法院判决,原告发码行实业(上海)有限公司法定代表人董事长徐蔚,诉李某利用网络媒体恶意诋毁其业务品牌码链应用技术,否认二维码扫一扫专利是原告发明的专利一案。经阿斯顿马丁剑指2030年电动车占半壁江山,上汽提前调转航向随着汽车圈绿色低碳浪潮愈演愈烈,豪华跑车品牌也纷纷触电。就在不久前,英国豪华汽车制造商阿斯顿马丁首席执行官TobiasMoers在路透社汽车峰会(ReutersEventsAuto外媒评2021十佳安卓手机,国产品牌占据半壁江山,华为竟落选了?不知不觉间,2021年已经过去大半,各手机品牌不断推出自己的新产品,尤其是在安卓阵营里,竞争尤为激烈。近日,著名科技权威媒体AndroidAuthority评选出了2021年截止目金地九龙壁别墅影音室私人定制和舒适度完美结合的典范基本情况简介实施方类别影音设计师案例类别私人影院位置及周边概括性描述佛山禅城金地九龙壁资金投入30万人民币(影音系统20万,声学装修10万)空间信息长8。42m宽4。42m高2。6百姓抱怨没钱,企业也说赚不到钱,社会财富都到了哪些人的手中?前言既然世界各国都觉得我们中国人的消费能力是很高的,为什么很多老百姓都说自己没有钱呢?还说生活压力大,供不起车,供不起房,甚至不敢生二胎,三胎。还有很多企业也跟着叫穷。百姓时常抱怨极氪确认陈奇加盟特斯拉辟谣青岛建厂腾讯重申无造车计划01hr华为自动驾驶团队创始人陈奇加入极氪今日,针对华为自动驾驶团队创始人自动驾驶研发部原部长陈奇加盟的消息,极氪给予了确认,其将任职自动驾驶副总裁,负责智能驾驶技术研发,向CEO仁战酒开放赋能,助力城市合伙人完成梦想,成就事业9你十心实意贵州仁战一九三五酒业有限公司的9名联合创始人(张文张应波周鸿黄训龙李守林王红张远钊覃程鹏李治仪)各自在品牌白酒影视互联网IP媒体等行业深耕了数十年,有着扎实的酱酒背景与数位观察全新查城市版块为你解析品牌跨城市拓店的必备方法近些年来,国家鼓励推动大数据与实体经济深度融合。党的十九大明确提出,要推动互联网人工智能大数据和实体经济的深度融合。由此可见,数字化经济已经成为大势所趋,现代化经济体系离不开大数据吉利帝豪GS地表8英里城市Live北京站开唱12月16日,吉利帝豪GS跨界酷狗音乐举办的地表8英里城市Live北京站在北京糖果俱乐部燃情开唱,地表8英里联合黑马rapper威尔携本场特邀嘉宾GAI周延好兄弟张千昊昊,与现场近亮点在这里!2020开学第一课被搬到了武汉一年一度的开学季来了,每年开学之际都会推出开学第一课。这一节目都是针对每年最重要的事件选定节目内容,有利于孩子们在潜移默化中受到熏陶。2020年开学第一课以少年强,中国强为主题,传
随着华为P50发布时间接近,几个值得关注的信息,看出华为很拼今年安卓手机市场里,最受大家关注的就是华为P50系列了,原本应该在今年3月份发布,但时间来到6月份依然没有任何官方消息透露,这让数亿花粉焦急难安,但是在6月2日的鸿蒙OS操作系统发国产手机个个冲击高端旗舰,618大促哪几款最值得买?在低端市场血拼性价比的同时,国产手机在近两年也一直在冲击高端市场,越来越多的品牌试图接近并冲击苹果三星在高端市场的地位。而且个个厂商都说自己发布的旗舰机是安卓机皇,机皇也很快成为烂折叠屏手机时代正式开启,三星小米OPPOVIVO下半年齐发随着超高端智能手机市场竞争的日益激烈,各手机品牌厂商开始在折叠屏上展开竞争,据悉,今年下半年,三星小米OPPOVIVO等品牌手机厂商都会推出其折叠手机产品。今年或将成为折叠屏手机发手机市场再迎洗牌,国产黑马反超苹果接替华为,连拿12个第一自从华为海思麒麟被限制后,就源源不断地传来华为业务受阻的消息,而关于芯片何时恢复,这件事却谁也说不准。而从理论上来讲,想要让美国放宽规则,台积电继续代工并出货华为,比登天还难。毕竟网红带货山寨手机后续下架朵唯中兴酷派等12个品牌知名博主科技小辛公开爆料,其通过某短视频平台购买网红二驴夫妇直播间朵唯手机,发现实物与直播间介绍原价4999元产品硬件差异极大,外观摄像头内存等都有造假嫌疑。一石激起千层浪,网友纷MIUI12。5稳定版第二批开始推送,这16款手机皆可升级,方法很简单小米手机的MIUI系统之前在手机行业中的形象一直都比较正面,因为在基于安卓定制的系统中,MIUI算是体验比较好的,不过可惜快速的发布新机,以及积极地听取用户意见不断改动,使得MIU快手永久清退朵唯产品9倍赔偿用户,但直播售假仍屡禁不止文AI财经社张可心编辑杨洁继薇娅带货山寨Supreme联名商品翻车后,快手头部主播驴嫂平荣再陷售假风波。日前,快手声明称,向所有在快手电商购买了朵唯12pro手机的消费者,在退款不行驶2万多公里纯电动别克微蓝6车主有话说买车已将近2年多,之所以看中新能源车型,也是响应国家政策,因为我们当地政府也在一直推广新能源车型,而且当时还有相应的补贴,我心想未来新能源也是整个个汽车行业的趋势,毕竟燃油车也越来续航可达上千公里,4月份成月销冠军,新款理想ONE上市随着目前国内新能源市场的车型越来越多,能达到续航上千公里的车型还是比较少的,而在新能源车型中,大部分都是混动版或纯电车型,通过增程式混动系统来驱动的车体,相信大家并陌生,在4月份中里程1000公里解决续航痛点,2021款理想ONE和比亚迪唐DMi选谁?汽车正在面临着再一次的大变革,从燃油车时代向全面电气化发展。许多城市限行政策下以及对新能源汽车的利好,燃油汽车已经不是最佳选择,然而,目前的纯电动汽车正在高速发展中,并不是解决出行北京现代落魄,理想汽车趁虚而入?新势力为传统车企纾困。5月27日,有媒体爆料称,已经停摆两年的北京现代第一工厂,将被理想汽车接手,打造成后者的全球旗舰生产基地。此外,据一张文件截图显示24日,理想汽车全球旗舰工厂