猿问

请问这个面试题如何分析?

var x = 20;

var a = {

    x: 15,

    fn: function() {

        var x = 30;

        return function() {

            return this.x;

        };

    }

};

console.log(a.fn());//function() {}

console.log((a.fn())());//20

console.log(a.fn()());//20

console.log(a.fn()() === (a.fn())());//true

console.log(a.fn().call(this));//20

console.log(a.fn().call(a));//15

说下我的理解:

  1. a.fn返回的是一个函数,直接将函数打印出来

  2. 返回1打印出的函数执行后的结果(为何this指向window还是无法理解)

  3. 同2

  4. 自执行函数(iife)的表示方法(function(){}())与function(){}()达到的是一样的效果,所以第四个console.log()打印出来的值是一样的

  5. this指代window,返回window.x也就是20

  6. 返回a.x也就是15

感觉还是理解不透彻,可否有高人指点一二?


慕容3067478
浏览 1001回答 2
2回答

慕桂英546537

第二个为什么是20?不该指向a吗?

POPMUISE

首先要明确的是this的几种指向情况。不赘述了,看这里此处有链接1.根据描述(a.fn())()执行的是哪个函数,执行的是(a.fun()),这个函数是a上的方法吗,有挂载的对象吗?没有,所以就属于对函数的直接调用,this就是window.2.(a.fn())(),a.fn()()根据优先级执行顺序是一样的(可以点进去看),且结果都是20.3.20===20,true.4.call的用法主要就是改变调用的函数(方法)的this值,a.fn().call(this)中的this,应该是当前环境的this,就是window。a.fn().call(a)就是传了a作为函数执行的this.补充:1.a.fn是a上的方法,a.fn()是a上方法的调用,其返回值是一个函数,a.fn()()是对这个函数的调用,于a的关系仅仅是能访问a.fn内声明的变量(函数作用域在声明时确定)。2.iife是(function())和(function())(),甚至!function()(),这些写法的功能都是讲函数声明变为函数表达式以可以直接调用而不保存。再看你说的a.fn()是函数声明吗?它就是对a.fn的一次调用,它就等于这次调用的返回值,就是一个单纯的函数。建议你先好好理解下返回值这个概念,再去查一下函数声明和函数表达式的区别。
随时随地看视频慕课网APP
我要回答