第一题:
1、考察js堆与栈:栈内存主要用于存储各种基本类型的变量,包括Boolean、Number、String、Undefined、Null以及对象变量的指针,堆主要存储object
所以字符串变量i,s以及对象指针a都存在栈中,new出来的对象开辟内存存在堆上,对应地址是指针a存的内容
2、考察参数传递按值传递:a是A类的实例,所以a.i='op',a.func(a.i)这句执行函数,把a.i作为参数传递,该函数会复制一个变量,两个变量完全独立,所以在函数体里只是把复制的那个变量(一个新的局部变量)改变为'op9’,在函数体外的a.i并没有被改变
另外补充说明ECMAScript中所有函数的参数都是按值传递的——《高程3》,其实对于参数是对象的情况,实际上也是按值传递,把传参的指针复制出一个完全独立的变量,只是存的内容和传参对象地址一摸一样https://www.cnblogs.com/chenwenhao/p/7009606.html
第二题:
'foo' //bind返回一个函数,该函数体中的this绑定到window上,然后new对该函数进行构造调用,返回一个新对象,函数体中的this指向该对象。bind是硬绑定,new绑定的优先级高于硬绑定。所以this还是绑定在bar这个新对象上。this.name='foo'就是bar.name='foo'
'foo2' //复杂类型值地复制是引用复制,bar3、bar2和bar指向的都是同一个对象,所以bar2.name='foo2'对对象的熟悉进行修改时,bar3和bar的数据同样收影响
'global' //setTimeout设置一个定时器,定时器到时后调用回调函数,但定时器到时后只能将回调的执行放到事件队列的末尾,不能插队,所以console.log(window.name)这条输出语句是最后执行的
第三题:
```
// 定时器任务属于宏任务,并且需要先在任务队列等待,等到同步任务执行完,执行栈清空,才会在任务队列中按顺序选任务进去
setTimeout(() => console.log('a'));//4. 打印a
//Promise 属于异步微任务,在本轮同步任务结束之前执行
Promise.resolve().then(
// 1. 打印 b
() => console.log('b’);
).then(
// 箭头函数的resolve传递的参数作为下一个then的参数
() => Promise.resolve('c').then(
// 执行立即执行函数
(data) => {
// 把定时器任务也放入任务队列中等待,在第一个定时器之后
setTimeout(() => console.log('d')); //5. 打印d
// 2.打印 f
console.log('f');
// 此时返回的 数据作为下一个then的参数
return data;
}
)
).then(data => console.log(data)); // 3.打印 c
```
* `打印bfcad`
第四题:
function Person(name) {
this.name = name
Person.prototype.greet = function() {
console.log('Hi, my name is' + this.name);
}
Person.prototype.greetDelay = function(time) {
var that = this
setTimeout(function() {
console.log('Hi, my name is' + that.name);
}, time);
}
}