Javascript中的this关键字、call和apply

this关键字的指向

this关键字的理解是在很多前端面试题中出现的题目,实际开发中用到的地方也非常多,这里写一下自己的理解~

在一个方法内部,this是一个特殊变量,它始终指向当前对象。this是动态的,可以改变的。
eg:

var n = { 
  name: 'abc', 
  getName: function () { 
            return this.name;
         }
};
n.getName; // function n.getName()
n.getName(); // abc

在上面这段代码中,age function中的this指向的就是n
换种方法写:

function getName() { 
  return this.name;
}
var n= { 
  name: 'abc', 
  gName: getName
};
n.gName(); // abc, 正常结果
getName(); // NaN

在这段代码中,n.gName()执行时,getName()中的this是指向n的,但是直接调用getName()时,this是指向全局变量window的。
如果把n.gName()赋给一个变量,像这样:

var name = n.gName;
name();

这个时候,function getName中的this却是指向window的,这是因为,在JS中,要保证this指向正确,必须用obj.xxx()的形式调用
有的时候,在函数内部又写了一个函数,像这样:

var n= { 
  name: 'abc', 
  getName: function () { 
      function getNewname() {
         return this.name; 
      } 
      return getNewname(); 
  }
};
n.getName();

这个时候,在getNewname()中的this,指向的就不是n了,而是window。原因是this指针只在getName方法的函数内指向n,在函数内部定义的函数getNewname()this又指向window了!
怎么解决这个问题呢?
getName函数中,用that变量获取到this,然后getNewname函数就可以使用这个that了,就像这样:

var n= { 
  name: 'abc', 
  getName: function () { 
    var that = this; // 在方法内部一开始就捕获this 
    function getNewname() { 
        return that.name; // 用that而不是this 
    } 
  return getNewname(); 
  }
};
n.getName();

这样,就可以放心地在函数内部使用this了。
另外JS中还有几种调用函数的方式:

  • 在标签内用onclick="show()"的方式调用show函数,这时由于是直接调用了show函数,因此show函数内部的this是指向window的,而如果是onclick="show(this);"这样写,就可以改变this的指向了。
  • addEventListener注册的函数,像这样:
name = 'window';
var a = document.getElementsByTagName('body');
a.addEventListener('click',show());
function show(){
   alert(this.name);
}

这时在屏幕上点击一下,alert出来的结果是'window',说明this指的是window

  • 作为构造方法调用,像这样:
function test(){     
   this.x = 1;   
}   
var o = new test();   
alert(o.x); // 1 

这里this指对象o,所谓构造函数,就是通过这个函数生成一个新对象(object)。这时,this就指这个新对象。
如果再通过test函数构造出一个对象p,像这样:

var p = new test();
alert(p.x);

这个时候,this指的p

call、apply的理解

附参考链接:https://www.zhihu.com/question/20289071
call和apply的存在,就是为了改变函数的调用对象,改变某个函数运行时的 context 即上下文,也就是改变this的指向。
二者的作用是一样的,只是传递参数的方式不一样。
call----把参数顺序传递进去,用,隔开
apply----把参数作为一个数组传递进去
eg:

func.call(this, arg1, arg2,arg3);
func.apply(this, [arg1, arg2,arg3]);

call和apply的应用场景:
在javascript OOP中,我们经常会这样定义:

function cat(){}
cat.prototype={     
   food:"fish",    
   say: function(){           
      alert("I love "+this.food);     
   }
}
var blackCat = new cat;
blackCat.say(); 

但是如果我们有一个对象whiteDog = {food:"bone"},我们不想对它重新定义say方法,那么我们可以通过callapplyblackCatsay方法:blackCat.say.call(whiteDog);
当一个object没有某个方法,但是其他的有,我们可以借助call或apply用其它对象的方法来操作。
另外,当你的参数是明确知道数量时,用 call,而不确定的时候,用 apply,然后把参数push 进数组传递进去。当参数数量不确定时,函数内部也可以通过 arguments这个数组来便利所有的参数。
注:
另外,当apply的参数为空时,this是指向window的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容