概述
关于javaScript中函数调用与函数上下文(this)的相关总结
首先理解js中函数调用,需要先理解函数是js中的一类对象。简单来说就是js中,函数也是一种对象,他们可以拥有属性、方法,也可以作为其他对象的属性或方法。也可以出现在对象能够出现的任何位置(例如函数也可以作为参数)。
一、函数调用与上下文
当我们在js中声明了一个a函数后,js中可能会出现四种不同方式的调用:
1.“作为一个函数”直接调用——例如: a()
2.作为一个方法调用——将a()函数关联在一个对象上再调用,例如: object.a()
3.作为一个构造函数调用—— 例如:new a()
4.通过函数的apply或者call方法调用——例如:a.apply(object) a.call(object)
情况1中,函数上下文(this的值)在严格模式下(use strict)为undefined,而在非严格模式下,将是全局上下文(window对象)。
情况2中,函数上下文将成为调用该函数的对象(object)。
情况3中,函数由关键字new调用,而new将会创建一个新的空对象,函数中的上下文将为这个新的空对象, new a()将返回一个新的对象作为函数的返回值(但要注意,若a()本来就返回一个对象类型的返回值obj,那么new a()最终将返回obj而不是由new创建的新的对象;若a() 本来返回的是非对象类型的返回值,那么 new a()将忽视a()的返回值,最终还是返回由new a() 创建的新的对象)。
情况4中,apply和call方法都接受显式的上下文,函数上下文为传入的object
二、经典例子
这里有一个比较经典的错误问题,摘抄自JavaScript忍者秘籍第二版第四章4.2.4小节
<button id="test">Clcik Me</button>
<script>
function Button(){
this.clicked = false;
this.click = function() {
this.clicked =true;
assert(button.clicked, "The button has been clicked");
};
}
// 此处作为构造函数调用,函数的上下文应该指向new创建的新的空对象
var button = new Button();
var elem = document.getElementById("test");
// 但此处为回调函数,上下文为触发回调时间的对象elem,即使使用button.click以方法的形式调用了定义的无名函数,传入的上下文也为elem
elem.addEventListener("click", button.click);
</script>
由上面的代码以及注释可以知道,这里的函数上下文并不是我们所期望的button,而是elem.为了解决这个问题,我们可以利用箭头函数。箭头函数的this与声明所在上下文相同,即从定义时所在函数继承上下文。
当将代码改为
function Button(){
this.clicked = false;
this.click = () => {
this.clicked = true;
assert(button.clicked, "The button has been clicked");
}
}
箭头函数在构造函数内部,从构造函数继承上下文(也就是new 所创建的新对象),当调用button.click时,确实时改变的button的属性clicked。不再会出现当回调函数执行时,传入的上下文为elem的情况。这样一来,我们在写前端一些接口函数的时候,调用回调函数的时候可以很好的避开一些问题。
如还有疑问可以参考JavaScript忍者秘籍第二版第四章相关内容。
最后
以上就是寒冷水壶为你收集整理的关于javaScript中函数调用与函数上下文(this)的相关总结的全部内容,希望文章能够帮你解决关于javaScript中函数调用与函数上下文(this)的相关总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复