面试题(最近遇到的)

1.下面这段代码,输出内容是什么,并说明为什么
A. 0 1 2 3     B. 0 0 0 0     C. 4 4 4 4    D. 3 3 3 3

var length = 4;
for(var i=0; i<length; i++){
    setTimeout(function ting(){
        console.log(i);
    }, 2000);
}

答案是C,原因如下:
setTimeout是异步调用的,且延迟两秒执行,因此等到setTimeout执行的时候,这个时候i的值已经变成了4,因此循环四次就会输出4个4。
以上是个人的理解,这里有更详细的介绍:戳我就能看了

2.下面那个选项是返回true的
A. null == undefined
B. null === undefined
C. null instanceof Object
D. NaN == NaN
答案是A,原因如下:
null和undefined是类似的值,undefined值是派生自null值的,因此A会返回true;可是又因为null和undefined的值虽然类似,可却是不同类型的值,因此B返回false;instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型,因此C返回false;因为NaN与任何值都不相等,包括NaN本身,因此D返回false

3.下面的代码返回的值分别是什么
A. 3 1     B. 1 2     C. 1 3     D. 2 1

// 第一段
var one = 1;
function ha (ha_val){
    ha_val = 2;
    ha2(ha_val);
}
function ha2(ha2_val){
    ha2_val = 3;
}
ha(one);
console.log(one);

// 第二段
var two = {
    'val': 1
};
function changeVal_1(two){
    two.val = 2;
    changeVal_2(two.val);
}
function changeVal_2(value){
    value = 3;
}
changeVal_1(two);
console.log(two.val);

答案是B,原因如下:

  • 这题考察的是局部变量跟全局变量的内容,第一段代码,只是将one的值传给函数ha,并赋值给函数局部变量ha_val,因此ha_val变量的值改变,不会影响变量one的值,所以最后输出的值是1。
  • 第二段代码,传给函数 changeVal_1的是对象two,而不是仅仅传了two的值,因此改变的是对象two的值;而传给函数changeVal_2的是two.val的值,改变它的值,不会改变对象two的值,因此最后输出的值是2。
    点击查看对应的参考文章

4.下面运用了哪个之后,左右上下偏移量无效
A. position: absolute
B. position: relative
C. position: fixed
D. position: static
答案是D,原因是:
static是position属性的默认值。这时候,我们称那个元素没有被定位,只有设置了定位之后,我们才能使用offset参数来为我们的元素指定我们想要的位置,否则top、left、right、bottom等偏移量设置无效

5.Ajax的请求有多少种Callback,分别是什么?
Ajax请求总共有八种Callback,分别是:onSuccess、onFailure、onUninitialized、onLoading、onLoaded、onInteractive、onComplete和onException。

6.ajax的同步请求跟异步请求的区别是什么?
同步请求:当执行当前ajax的时候会停止执行后面的JS代码,直到ajax执行完毕后时,才能继续执行后面的JS代码。
异步请求:当ajax发送请求后,在等待server端返回的这个过程中,前台会继续 执行ajax块后面的脚本,直到server端返回正确的结果才会去执行success,也就是说这时候执行的是两个线程,ajax块发出请求后一个线程 和ajax块后面的脚本(另一个线程)
参考文章:
AJAX中同步和异步的区别和使用
同步请求和异步请求的区别

7.用javascript写一个一秒的定时任务,一秒之后弹出弹窗,内容是“你好”

// 我当时的做法是这样的
var isPause =  false;
var startTime = new Date().getTime();
while(!isPause){
   var nowTime = new Date().getTime();
   if (nowTime - startTime >= 1000) {
       window.alert('你好');
       isPause = true;
   }
}

结束后去网上看看有没有更好的方法,发现网上大部分是直接用setTimeout的,看来是我想太多了?

8.说说对前端工程化的理解

前端工程化

  • 使用软件工程的技术和方法来进行前端项目的开发、维护和管理
  • 所有能降低成本,并且能提高效率的事情的总称为工程化
  • 软件工程化关注的是性能、稳定性、可用性、可维护性等方面,一切以这些为目标的工作都是"前端工程化"
前端工程化分为这四个部分:规范化,自动化,模块化,组件化。

下面是一些详细解析上面四个部分内容的参考文章:
1.https://www.jianshu.com/p/2e096d7d3e03
2.http://www.xuefeng666.com/WebGCH/WebGCH/#%E5%BD%92%E7%B1%BB%E6%8F%8F%E8%BF%B0
3.https://segmentfault.com/a/1190000009815823

9.下面的代码最终的结果会输入什么?

function Test(){
    this.a = 0;
    this.b = function(){
        alert(this.a);
    }
}
Test.prototype = {
    b: function(){
        this.a = 20;
        alert(a);
    },
    c: (function(){
        this.a = 20;
        alert(this.a);
    })()
};
var fanshu = new Test();
fanshu.b();
fanshu.c;

fanshu.b()弹出的数字是:0
fanshu.c弹出的数字是:20
原因是:fanshu是Test的实例,当调用fanshu.b()时,会先在实例上查找有没有b属性,发现有对应的b属性,因此不会继续往上查找,因此弹出的值是0;当调用fanshu.c时,在实例没有查找到对应的属性,因此继续在原型对象上查找,查找到对应的c属性, c属性是一个立即执行的函数,因此可以直接执行,弹出值20。

10.事件委托的优点,如何优化?
优点:1.减少事件处理程序的绑定,节省内存;2.减少dom节点操作,提高性能
优化:1.降低层级,把事件绑定在低层级的元素上,不在body元素或者document上绑定;2.即使是用事件委托,也要减少绑定的次数。
参考文章:深入理解-事件委托事件委托优缺点

11.用javaScript写一个用来替换replace方法的方法,替换掉下面的字符串

var type = { "company": "信息科技公司", "adjective": "领导nice" };
var date = "{{ company }} {{ adjective }},而且人才很多。";

额外思考:type的顺序可以跟字符串里面的变量顺序不一致,以及字符串的变量不一定存在于type中。
代码如下:

function replaceString(type, string){
    var result = [];
    // 对字符串进行第一次切割
    var items = string.split("{{");
    // 循环切割后得到的数组
    for(var i=0; i<items.length; i++){
        var item = items[i];
        // 对有“}}”的字符串进行二次切割,没有则放进新数组中
        if(item.indexOf('}}') !== -1){
            var pieces = item.split("}}");
            // 获取对应的映射值,并放进新数组中
            var mappingVal = type[pieces[0]] ? type[pieces[0]] : ("{{" + pieces[0] + "}}");
            result.push(mappingVal);
            // 若"}}"后面还有字符串,则放进新数组中
            if(pieces.length > 1 && pieces[1] !== ''){
                result.push(pieces[1]);
            }
        }
        else if(item !== ''){
            result.push(item);
        }
    }
    // 连接数组中各项
    var result = result.join('');
    return result;
}

后来跟朋友讨论了下,发现还可以用递归+substring的方法:

function replaceString(type, stringVal){
    var startIndex = 0;
    var res = '';
    function runStr(stringVal, startIndex){
        var leftIndex = stringVal.indexOf('{{', startIndex);
        var rightIndex = stringVal.indexOf("}}", startIndex);
        if(leftIndex !== -1 && rightIndex !== -1){
            var val = stringVal.substring(leftIndex + 2, rightIndex);
            if(type[val]){
                res = stringVal.substring(0, leftIndex) + type[val] + stringVal.substring(rightIndex + 2, stringVal.length);
                startIndex = res.indexOf("{{");
            }
            else {
                startIndex = res.indexOf("}}") + 2;
            }
            runStr(res, startIndex);
        }
    }
    runStr(stringVal, startIndex);
    return (res !== '' ? res : stringVal);
}

猜你喜欢

转载自blog.csdn.net/weixin_34236497/article/details/90793358