JavaScript里的小妖精

JavaScript里的小妖精———this!!

关于this指向这个问题,活生生折磨了我一个下午,回来静下心捋顺一下,总结出来一下规律。

当然,this这个复杂的问题不是一句两句可以说清楚,作为菜鸟,我的总结也就是为了做一些 ‘坑人的’ 笔试题,所以只能欢迎吐槽了。


题中一般分为两种情况

  • 调用者是函数

    • 函数通过对象被调用(this指向对象 )
    • 函数单独被调用(this指向undefined,非严格模式下指向全局)
  • 调用者是对象
    • 对象声明在函数中 (this指向undefined,非严格模式下指向全局)
    • 对象声明在函数外 (this指向全局)

PS:匿名函数的存在会导致this指向的丢失与以上情况不符合,用bind()来解决就可以了


举一些栗子??????

  • 栗子??一

    var a = 1;
      var obj = {
          a:2,
          c:this.a + 10,
          b: function () {
              return this.a;
          }
    }
    console.log(obj.b()); //函数b通过对象obj被调用,this指向obj【2】
    console.log(obj.c); //对象声明在函数外,this指向全局【11】
  • 栗子??二
    var o = {
      a:10,
      b:{
          a:12,
          fn:function(){
              console.log(this.a);
          }
      }
    }
    o.b.fn();//fn通过对象被b调用,this指向b【12】
  • 栗子??三
    var o = {
      a:10,
      b:{
          a:12,
          fn:function(){
              console.log(this.a);
              console.log(this);
          }
      }
    }
    var j = o.b.fn;//fn未被执行
    j();//此时fn单独被调用,this指向全局,全局没有a【undefined】【window】
  • 栗子??四
    var name = ‘222‘;
      var a = {
          name:‘111‘,
          say:function () {
              console.log(this.name);
          }
      }
      var fun = a.say;//say未被执行
      fun();//say单独被执行,this指向全局【222】
      a.say();//函数say通过对象a被调用,this指向对象a【111】
      var b = {
          name: ‘333‘,
          say: function (fun) {
              fun();
          }
      }
      b.say(a.say);//a.say未被执行
      fun();//say单独执行,this指向全局【222】
      /*b.say(function(){}),但是通过b对象调用的函数say被执行,this指向b,。
       但此时的this不是我们要打印的this,我们要打印的this在function(){}里,function里的this指向全局
       */
      b.say = a.say;//a.say未被执行,将function赋值给了b,此时b对象也可以打印啦!
      b.say();//say函数被对象b调用执行,this指向b【333】
  • 栗子??五
    var name = ‘global‘;
    var obj = {
      name: ‘obj‘,
      getName: function () {
          return function () {
              console.log(this.name);
          }
      }
    }
    obj.getName()();//【global】
    /*
    var fn = obj.getName();
    fn();
    */

call和apply改变this指向

  • call和apply的第一个参数都是this的指向
  • call的其他参数是一个一个传的
  • apply的其他参数以数组形式传递。
    function fn(a,b,c) {
      console.log(this.a + a + b + c);
    }
    var obj = {
      a: 20
    }
    fn.call(obj, 10, 20, 30);//【80】
    fn.apply(obj, [100, 200, 300]);//【620】
  • 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入学习交流群
    343599877,我们一起学前端!
时间: 2024-11-10 07:59:33

JavaScript里的小妖精的相关文章

map这个小妖精(*/ω\*)

1. map是虾米咩 redis晓得咩,就是那个key-value结构的数据库,map这家伙其实就是key-value结构的容器.容器是虾米咩,还好之前看过有关的一丁点,晓得C++里有这个一种类存在,它的名字就叫做容~器~类~~~网上说,容器就是用来存储数据的咩.map是标准STL关联容器,反正有概念就好得了咩,不必太纠结了o( ̄ヘ ̄o#) 2. 它是谁家小妖精咩 来来来,让俺们看看,这小妖精的头文件是哪个咩 #include <map> 既然是map,当然是map家的,有木有猜到咩哈哈哈哈

javascript里for循环的一些事情

今天在给一个学妹调她的代码BUG时,她的问题就是在一个for循环里不清楚流程的具体流向,所以导致了页面怎么调都是有问题,嗯确实你如果不清楚语句流向很轻易就会出问题,所以说for循环不会用或者说用的不恰当还是很可怕的.我也借此机会顺带复习了一下javascript里的for()循环.翻出了自己以前关于for循环的一些笔记,有些内容跃然浮于脑海中,以下大部分来自很久之前的笔记,可能会有一部分来自于网上其他优秀博客的内容. for循环里共有三个流程语句,这三个部分之间用";"分开.第一个是一

JavaScript里call,apply,bind方法简介

JavaScript里call,apply,bind方法不太容易理解,其实背后的思想并不算非常复杂,希望本文能帮你更好地了解这3个很像,而且看似很神秘的方法. 非要用一个关键字来点明它们的背后思想的精髓的话,关键字就是:this 因为通常程序员对C++比较熟,先借用C++,简单说一下this. 类的成员函数里,都可以用this来访问当前类的成员,但问题是成员函数的参数并没有this这个参数,比如: Animal a; a.eat(); a.eat("meat"); Animal的对象调

( 译、持续更新 ) JavaScript 上分小技巧(二)

考虑到文章过长,不便于阅读,这里分出第二篇,如有后续,每15个知识点分为一篇... #29 - 使用缓存的记忆让递归函数加速运行波非那切数列(Fibonacci sequence)想必大家都不陌生(针对学霸而言,在这之前本兽完全不知道这是个什么鬼,虽然经常会用到递归),我们可以在20秒内写出以下的函数: var fibonacci = function(n){ return n < 2 ? n : fibonacci(n-1) + fibonacci(n-2); } 它确实是运行了,但是效率并不

私人定制javascript中函数小知识点

函数的定义 首先在javascript中,函数就是对象,程序可以随意操控它们.比如,可以给它们设置属性,甚至调用它们的方法.函数使用function关键字来定义.它既可以用在函数定义表达式,也可以用在函数声明语句中.函数声明function后面必须要更上函数名称也就是所谓的函数名称标识符.如果是函数表达式函数名称标识符可有可无.这段重点是函数是对象,所以函数表现出来的种种行为你想想成对象,那么很多疑惑可能就恍如昨日初见. 函数调用 4种方式来调用javascript函数: 1.作为函数 就是函数

JavaScript apply函数小案例

//回调函数1 function callback(a,b,c) { alert(a+b+c); } //回调函数2 function callback2(a,b) { alert(a+b); } //这个方法做了一些操作.然后调用回调函数 function doCallback(fn,args) { fn.apply(this, args); } function test() { //动态调用方法.并传递参数 doCallback(callback2,['a','b']); doCallba

小妖精的完美游戏教室——东方PROJECT,同人,墙

//================================================================//// Copyright (C) 东方同人社// All Rights Reserved//// Author:小妖精Balous// //Summary:墙是很重要的,除非你想让玩家穿模.因为墙只有一个,所以就用静态的Singleton实现了 ////=======================================================

JavaScript里关于声明的一些重要概念

所有的全局变量都是window的属性,在函数体外定义的var a=1等价于window.a=1: 所有的变量声明都在范围作用域的顶部,因为JS引擎首先会扫描所有的变量声明,然后将这些声明移动到顶部: 变量声明被提前了,变量赋值却没有.当变量声明和变量赋值一起使用时,JS引擎会自动将它分为两部分,以便将变量声明提前,不将赋值提前是因为可能影响代码执行出不可预期的结果: 函数声明也是提前的,所有的函数声明都在执行代码之前都已经完成了声明,和变量声明一样.但函数表达式不会提前,相当于变量赋值: 函数声

私人定制javascript中数组小知识点(Only For Me)

先上笑话,1.刚看到一个游泳的,想起公司组织去三亚旅游,老板跳海里,各种挣扎,捞上来老板第一句话:我记得我会游泳的啊. 2.媳妇说:老公对不起,我把你新买的自行车撞散架了! 老公:没事宝贝,你若安好,便是晴天! 媳妇说:老公你太有诗意了. 老公:滚犊子,安不好我整死你! 数组的概念 javascript数组是值得有序集合,不过它实属一个javascript对象的特殊形式,这是一个很重点的定性. 创建数组 1.var a=new Array();//等同于[] 2.var a=new Array(