牛客_美团点评2020校招前端笔试题(仅个人学习记录)

1.(问答题)
题目描述

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的值是什么?

1、i,s,a都在栈中,new出来的对象A在堆上。
考察js堆与栈:
栈内存主要用于存储各种基本类型的变量,包括Boolean、Number、String、Undefined、Null以及对象变量的指针;堆主要存储new出来的对象。
所以字符串变量i,s以及对象指针a都存在栈中,new出来的对象开辟内存存在堆上,对应地址是指针a存的内容
2、执行完后a.i的值还是字符串op。
考察参数传递按值传递:a是A类的实例,所以a.i=‘op’,a.func(a.i)这句执行函数,把a.i作为参数传递,该函数会复制一个变量,两个变量完全独立,所以在函数体里只是把复制的那个变量(一个新的局部变量)改变为’op9’,在函数体外的a.i并没有被改变
另外补充说明ECMAScript中所有函数的参数都是按值传递的——《高程3》,其实对于参数是对象的情况,实际上也是按值传递,把传参的指针复制出一个完全独立的变量,只是存的内容和传参对象地址一摸一样
JS中函数参数值传递和引用传递

2.(问答题)
请按顺序写出打印结果,并说明原因。

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);

第10行的console是在定时器函数中,因此最后执行。
首先输出第12行bar调用name,由于第8行var bar = new obj.foo(); new绑定的优先级大于bind绑定,所以函数内部this还是obj {},输出foo。
再输出第16行console.log(bar3.name),bar3=bar2=bar,bar3/bar2/bar都是指向同一个对象,因此输出bar中的foo2。
最后输出定时器里的window.name,即global。

参考JS的this问题JS this指向总结
哪个对象调用函数,函数里面的this指向哪个对象。
this 主要是在函数中使用,在函数外使用,一律指向全局对象。
在函数内使用 this 时,具体指向是由函数的调用方式决定,而不是根据函数定义方式决定。

  1. 函数作为普通函数运行时,可以看做是当做全局对象的方法运行,此时 this 指向全局对象
  2. 函数作为对象的方法调用时,函数内的 this 指向该对象
  3. apply call bind 改变 this 指向,bind 不会受到 apply 和 call 影响,bind优先级最高。一旦经历过bind函数,后面全输出bind指向的值。
  4. 定时器setTimeout设置的函数,this 会指向全局。bind 强制绑定优先级最高,不受定时器影响。
  5. ES6 箭头函数
    ES6 的箭头函数没有自己的 this 和 arguments, 因此在箭头函数内部使用 this 和 argments, 其实使用的是外层的 this 和 arguments。由于箭头函数没有自己的this,所以当然也就不能用call()、apply()、bind()这些方法去改变this的指向。优先级高于bind

3.(问答题)
题目描述
请写出如下代码运行后产生的结果,并给出解释,说明结果是如何得出的。

setTimeout(() => console.log('a'));
Promise.resolve().then(
   () => console.log('b’);
 ).then(
   () => Promise.resolve('c').then(
     (data) => {
   
       setTimeout(() => console.log('d'));
       console.log('f');
       return data;
     }
   )
 ).then(data => console.log(data));

b f c a d 解析戳此

JS的setTimeout和Promise——同步异步和微任务宏任务
这一次,彻底弄懂 JavaScript 执行机制(这一篇我看的最明白,👏🌸)

macro-task(宏任务):包括整体代码script,setTimeout,setInterval
micro-task(微任务):Promise,process.nextTick
不同类型的任务会进入对应的Event Queue,比如 setTimeout 和 setInterval 会进入相同的Event Queue。
事件循环的顺序,决定js代码的执行顺序。进入整体代码(宏任务)后,开始第一次循环。接着执行所有的微任务。然后再次从宏任务开始,找到其中一个任务队列执行完毕,再执行所有的微任务。
一般看到单独的console.log(),new Promise()都是直接输出,把then, process.nextTick扔到微任务的队列里等待按序执行,把setTimeout扔到宏任务的队列里等待按序执行。

延伸题:

console.log('1'); 
setTimeout(function() {
   
    console.log('2'
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值