资讯专栏INFORMATION COLUMN

一道笔试题引发的思考

soasme / 3228人阅读

摘要:前两天做了一份笔试题按照执行顺序列出下面代码的打印内容可能有些小朋友会被里面那个立即执行函数吓傻。和将指向改变至,也就是了。

前两天做了一份笔试题:按照执行顺序列出下面代码的打印内容

var name = "The Window";
var object = {
    name : "The Object",
    getNameFunc : function(){
        (() => {
            console.log(this.name)
        })()
        return function(){
            console.log(this.name)
        };
    }
};
var func = object.getNameFunc();
func();
func.call(object);
func.apply(object);

可能有些小朋友会被里面那个立即执行函数吓傻。没关系,先看答案,整段代码输入浏览器,输出如下:

The Object

The Window

The Object

The Object

OK, 一个一个来分析。

执行顺序从上往下,这句var func = object.getNameFunc();会产生第一个输出:The Object
想搞明白为什么输出这个,必须先知道,this指向谁?
首先,想知道this指向谁,不能看它在哪里被定义,而要看它在哪里被调用,运行object.getNameFunc()时,显而易见地,调用这个函数的是object,立即执行函数里面的this指向objectthis.name自然就是object.name

因此输出The Object

那么,接下来,func被赋了什么值?整个getNameFunc()函数吗?

并不是的,object.getNameFunc()函数运行的时候,闭包那段代码没有被执行,只是作为返回结果赋给了func,因此事实上var func = object.getNameFunc()这句等价于:

var func = function() {
     console.log(this.name)
}

现在funcobject就已经没什么关系了,func里面的this自然指向window
因此第二句执行语句func()相似于(注意用词,我这里用的是相似,不是相等):

object.getNameFunc()() //是的,我没打错,两个括号

嘻嘻,是不是有点蒙圈?

上面说了,由于object.getNameFunc()执行后,会对外暴露出一个匿名函数,即return返回的那个匿名函数

function () {
    console.log(this.name)
}

所以object.getNameFunc()()会调起立即执行函数

(function () {
    console.log(this.name)
})()

注意 —— object.getNameFunc()()这个写法只是为了能调用闭包函数,如果在真的在浏览器跑object.getNameFunc()(),事实上会顺序执行输出两个结果:一个是立即执行函数的结果,一个是闭包函数的结果。

由于object.getNameFunc()赋值给了func,因而使用func()就可以只调用闭包,而不触碰那个立即执行函数。这几句话要小心理解!

通常一个变量未被声明就使用,会指向window.undefined,然而this是不会指向undefined的,像我们平时定义一个普通函数

function app() {}
// 调用
app()
// 实际上是这样调用的
window.app()

所以this会指向windowfunc()自然也等于window.func(),调用方是windowthis.name即是window.name

理解了上面那些,接下来的两句反倒是简单了。

func.call(object);
func.apply(object);

callapplythis指向改变至objectthis.name也就是object.name了。

本来写这篇博客之前还是有点绕的,写完之后脑子就清晰了,相信以后这类题能轻松答上。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84454.html

相关文章

  • 一道setTimeout async promise执行顺序试题引发思考

    摘要:如果你要问他和谁当进去的快,要从下面两个方面考虑结束时。至于什么,查了很多的资料,了解到一个浏览器环境只能有一个事件循环,而一个事件循环可以有多个任务队列。 ====据说这是今日头条去年的一道笔试题,主要考察的是setTimeout async promise执行顺序 ~先双手奉上这道题目~ async function async1() { consol...

    soasme 评论0 收藏0
  • 一道2016年nice校招试题引发思考

    摘要:注意点这个代码是严格依赖环境的,例如中和是连续的,在编译器中,和之间有一个空间。注意点当把与交换之后,程序将不会出现死循环,但是程序的越界访问报错是少不了的。注意点这种优化是无差别的,即无论你的代码是否越界,都会进行这样的优化。 目录 声明 原题 题目详细解析 运行结果: 题目...

    shixinzhang 评论0 收藏0
  • 一道试题引发Promise

    摘要:对象是一个返回值的代理,这个返回值在对象创建时未必已知。这使得异步方法可以像同步方法那样返回值异步方法会返回一个包含了原返回值的对象来替代原返回值。 前言 近来参加校招笔试,发现有好几道关于Promise的题目。然而我都没有了解过。所以,这篇文章以网易笔试的一道题开始,记录关于Promise的那些事。文章地址:http://lsxj615.com/2016/08/04... 笔试题 c...

    _Suqin 评论0 收藏0
  • 一道三目运算测试题引发思考

    摘要:因为加法的优先级比条件运算符高,所以先运算加号,是字符串拼接,结果是非空字符串,在中字符串的布尔类型为。知识点三目运算为真执行为假执行运算优先级在中布尔类型只有以下种情况为假,其他都为真。 一、测试题 原题:以下代码的输出是? var val = false; alert(val is + val ? true : false); 解析: 1. 此题考察的知识点: 三目运算、**运...

    SHERlocked93 评论0 收藏0
  • 一道JS试题引发思考

    摘要:也给当初出入迷宫的我不小考验,一道题目可以引发许多思考,今天写下的只是今时今日的想法,到未来也许还有别样的看法。对于回调函数,可以对其传入三个参数分别是当前元素,元素索引,调用的数组。 [1,2,3].map(parseInt) 这道JS题目,相信大家并不会陌生。也给当初出入JS迷宫的我不小考验,一道题目可以引发许多思考,今天写下的只是今时今日的想法,到未来也许还有别样的看法。...

    xiao7cn 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<