美团前端2020校招笔试小记

明天要做米哈游的校招笔试,可能是综合卷也可能不是,前端这边先刷了点题。

在美团前端2020校招笔试的卷子里面碰到两个比较生疏的前端题,拿出来记录一下。

Keyword: 堆内存/栈内存,bind与this

题A

1
2
3
4
5
6
7
8
9
10
class A {
String i = "op";
void func(String s) {
s = ""+9;
}
static void test() {
A a = new A();
a.func(a.i);
}
}

问:

  1. 变量i,s,a在堆还是在栈中?
  2. 第8行执行完后a.i的值是什么?

第二问不难,a.i没有改变过,输出一定是“op”,难点在第一问。对于堆内存和栈内存的理解这题考的很到位,我答题的时候认为a在堆内存,其实i、s、a都在栈内存里面。

栈内存存放的是各种基本的变量,以及指向对象的指针,堆内存里面存放的一般是对象。i、s在栈内存不难理解,重点在于a。

1
A a = new A();

重点在于这个a是什么,实际上a并不是A本地,而是指向A的、放置于栈内存的指针,所以a也在栈内存里,只有A这个对象的本体在堆内存。

题B

按顺序写出打印结果,并说明原因:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var name = 'global';
var obj = {
name: 'local',
foo: function(){
this.name = 'foo';
}.bind(window)
};
var bar = new obj.foo();
setTimeout(function() {
console.log(window.name);
}, 0);
console.log(bar.name);

var bar3 = bar2 = bar;
bar2.name = 'foo2';
console.log(bar3.name);

这个题里面最后一行的输出很简单理解,就是'foo2',这个没啥说的,主要是前面两个输出涉及到bind。

1
var bar = new obj.foo();

这一行里面,obj.foo()看似是把内部的this绑定到了window上,实际上对于绑定new的优先级高于bind,所以这个bind是不会做的,对于得到的bar其内部的this还是指向bar自己。

所以第一个输出的bar.name还是'foo'。

由于没有绑定window,所以window的name没有被改变,自然最后是输出一个'global'(setTimeout滞后执行)。

小结

这两个题目搞明白了原理就很简单了,主要是背后的基础知识问题,算是JavaScript里面基础常规的题目。