博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Javascript中的this关键字、call和apply
阅读量:5063 次
发布时间:2019-06-12

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

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的理解

附参考链接:

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的。

转载于:https://www.cnblogs.com/feeiluuo/p/5204263.html

你可能感兴趣的文章
Python 3语法小记(九) 异常 Exception
查看>>
DSP TMS320C6000基础学习(4)—— cmd文件分析
查看>>
角色权限etmvc+jQuery EasyUI+combobox多值操作实现角色授权
查看>>
Prototype Pattern
查看>>
前端工具----iconfont
查看>>
过完年了,要不要辞职?
查看>>
每天一个linux命令(57):ss命令
查看>>
Javascript获得当前网页页面详细地址的实现
查看>>
tcp ip协议讲解
查看>>
linux内核系统调用和标准C库函数的关系分析
查看>>
nginx log 错误502 upstream sent too big header while reading response header from upstream
查看>>
CGI,FastCGI,PHP-CGI与PHP-FPM(转)
查看>>
学习陆汝铃老师一篇序言有感
查看>>
Tcpdump
查看>>
Android TabHost中使用startActivityForResult无法接收返回值的解决方案
查看>>
做一些面试题目(JavaScript部分)
查看>>
Azure Site Recovery 通过一键式流程将虚拟机故障转移至 Azure虚拟机
查看>>
Hello China操作系统STM32移植指南(一)
查看>>
cocos2dx CCEditBox
查看>>
VC++2012编程演练数据结构《8》回溯法解决迷宫问题
查看>>