在javascript中,<code>this</code> 表示函数调用上下文。<code>this</code>难点在于它有一个复杂的行为,这也是面试中经常被考的点。
本文列举<code>7</code>个关于<code>this</code>有趣的面试问题:
问题1:变量 vs 属性
问题2:cat 的名字
问题3:延迟打招呼
问题4:人工方法
问题5:问候和告别
问题6:棘手的 length
问题7:调用参数
下面的打印结果是啥:
答案:<code>'hello, world!'</code>
<code>object.getmessage()</code>是一个方法调用,此时的 <code>this</code> 表示 <code>object</code>。
方法还有一个变量声明<code>const message = 'hello, earth!'</code>。这个变量都不会影响<code>this.message</code>的值。
下面代码打印什么:
答案:<code>'fluffy'</code> 和 <code>'fluffy'</code>
当函数作为构造函数<code>new pet('fluffy')</code>调用时,构造函数内部的<code>this</code>等于构造的对象
<code>pet</code>构造函数中的<code>this.name = name</code>表达式在构造的对象上创建<code>name</code>属性。
<code>this.getname = () => this.name</code>在构造的对象上创建方法<code>getname</code>。 而且由于使用了箭头函数,箭头函数内部的<code>this</code>值等于外部作用域的<code>this</code>值, 即 <code>pet</code>。
调用<code>cat.getname()</code>以及<code>getname()</code>会返回表达式<code>this.name</code>,其计算结果为<code>'fluffy'</code>。前端培训
答案:1秒后,打印 <code>undefined</code>。
尽管<code>settimeout()</code>函数使用<code>object.logmessage</code>作为回调,但仍将<code>object.logmessage</code>用作常规函数,而不是方法。
在常规函数调用期间,<code>this</code>等于全局对象,即浏览器环境中的 window。
这就是为什么<code>logmessage</code>方法中的 <code>this.message</code>等于 <code>window.message</code>,即<code>undefined</code>。
如何调用<code>logmessage</code>函数,让它打印 <code>"hello, world!"</code> ?
答案:
至少有 3 种方式,可以做到:
答案: <code>'hello, world!'</code> 和 <code>'goodbye, undefined!'</code>。
当调用<code>object.greet()</code>时,在<code>greet()</code>方法内部,<code>this</code>值等于 object,因为<code>greet</code>是一个常规函数。因此<code>object.greet()</code>返回<code>'hello, world!'</code>。
但是<code>farewell()</code>是一个箭头函数,箭头函数中的<code>this</code>值总是等于外部作用域中的<code>this</code>值。
<code>farewell()</code>的外部作用域是全局作用域,它是全局对象。因此<code>object.farewell()</code>实际上返回<code>'goodbye, ${window.who}!'</code>,它的结果为<code>'goodbye, undefined!'</code>。
答案: <code>4</code>
<code>callback()</code>是在<code>method()</code>内部使用常规函数调用来调用的。由于在常规函数调用期间的<code>this</code>值等于全局对象,所以<code>this.length</code>结果为<code>window.length</code>。。
第一个语句<code>var length = 4</code>,处于最外层的作用域,在全局对象 <code>window</code> 上创建一个属性<code>length</code>。
答案: <code>3</code>
<code>obj.method(callback, 1, 2)</code>被调用时有<code>3</code>个参数:<code>callback</code>, <code>1</code>和<code>2</code>。结果,<code>method()</code>内部的参数特殊变量是如下结构的数组类对象:
因为<code>arguments[0]()</code>是arguments对象上的回调的方法调用,所以回调内部的参数等于<code>arguments</code>。 所以 <code>callback()</code>中的<code>this.length</code>与<code>arguments.length</code>相同,即<code>3</code>。
~ 完,我是小智,我要去刷碗了,我们下期见!
代码部署后可能存在的bug没法实时知道,事后为了解决这些bug,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的bug监控工具 fundebug。