8-4 每日刷题


美团2020校招前端方向笔试题(链接)

问答题

1>

1

1、考察js堆与栈:栈内存主要用于存储各种基本类型的变量,包括BooleanNumberStringUndefinedNull以及对象变量的指针,主要存储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

2>

2

var name = 'global';
var obj = {
    name: 'local',
    foo: function(){
        console.log(this)
        this.name = 'foo';
    }.bind(window)
};
console.log(obj.foo());// 此时调用的this是window
// 由于new绑定的优先级大于bind绑定,所以函数内部this还是obj {}
var bar = new obj.foo();
console.log(bar);//{name:'foo'}
console.log(window.name);//global

// 定时器任务,在最后放入任务队列,window对象没有被改变,所以输出 'global'
setTimeout(function() {
    console.log(window.name);
}, 0);
// 此时bar.name =foo,因为被赋值了
console.log(bar.name);

// 此时执行顺序是var bar3,bar2=bar,bar3=bar2, 所以bar3/bar2/bar都是指向同一个对象
var bar3 = bar2 = bar;
bar2.name = 'foo2';
// 所以bar2修改属性,bar3的也改变了,此时输出为'foo2'
console.log(bar3.name);

‘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)这条输出语句是最后执行的

3>

3

// 解析1:
// 定时器任务属于宏任务,并且需要先在任务队列等待,等到同步任务执行完,执行栈清空,才会在任务队列中按顺序选任务进去
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`
// 解析2:
// setTimeout是异步任务中的宏任务
setTimeout(() => console.log('a'));
 
// Promise是异步任务中的微任务。比setTimeout先执行,
链式执行法,遇到setTimeout先挂起,往下执行
Promise.resolve().then(
   () => console.log('b')  // 输出 'b'
 ).then(
    //该函数返回值是 'c'
   () => Promise.resolve('c').then(
     (data) => {
       setTimeout(() => console.log('d'));  //挂起,放到宏任务队列之后
       console.log('f');  //执行,输出'f'
       return data;
     }
   )
 ).then(data => console.log(data) ); // 接收到的就是输出 'c'
 
// 执行宏任务
setTimeout(() => console.log('a'));  //输出 'a'
// 后续添加的宏任务
 setTimeout(() => console.log('d'));  //输出 'd'

4>

4-1

4-2

ES6与 ES5对比

4-3

var Person = (function () {
    function Person (name){
        this._name = name;
    }
    Person.prototype.greet = function() {
        console.log("Hi, my name is " + this._name);
    }
    Person.prototype.greetDelay = function(time) {
        var _this = this;
        setTimeout(function () {
            console.log("Hi, my name is " + _this.name);
        }, time);
    }
})();

**setTimeout() **调用的代码运行在与所在函数完全分离的执行环境上。这会导致这些代码中包含的 this 关键字会指向 window (或全局)对象

解决方法:

  • 1.使用局部变量:

    var _this=this;
    setTimeout(function() {
    console.log("Hi, my name is "+_this.name);
    }, time);
    
  • 2.使用箭头函数:

    setTimeout(() => {
    console.log("Hi, my name is "+_this.name);
    }, time);
    
  • 3.bind函数:

    bind()方法是在Function.prototype上的一个方法,当被绑定函数执行时,bind方***创建一个新函数,并将第一个参数作为新函数运行时的this
    

编程题

5>

5


文章作者: Zetai Wei
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Zetai Wei !
评论
  目录