js基础面试题81-91道题目(js基础面试笔试题)

81.call 与 apply 区别

参考答案:第二个参数的类型不同

解析:

call 和 apply 的作用,完全一样,唯一的区别就是在参数上面。

call 接收的参数不固定,第一个参数是函数体内 this 的指向,第二个参数以下是依次传入的参数。

apply 接收两个参数,第一个参数也是函数体内 this 的指向。第二个参数是一个集合对象(数组或者类数组)

参与互动

82.正则表达式构造函数 var reg = new RegExp('xxx')与正则表达字面量 var reg = // 有什么不同?

参考答案:使用正则表达字面量的效率更高

解析:下面的示例代码演示了两种可用于创建正则表达式以匹配反斜杠的方法:

//正则表达字面量
var re = /\\/gm;

//正则构造函数
var reg = new RegExp("\\\\", "gm");

var foo = "abc\\123"; // foo的值为"abc\123"
console.log(re.test(foo)); //true
console.log(reg.test(foo)); //true

如上面的代码中可以看到,使用正则表达式字面量表示法时式子显得更加简短,而且不用按照类似类(class-like)的构造函数方式思考。

其次,在当使用构造函数的时候,在这里要使用四个反斜杠才能匹配单个反斜杠。这使得正则表达式模式显得更长,更加难以阅读和修改。正确来说,当使用 RegExp()构造函数的时候,不仅需要转义引号(即"表示"),并且通常还需要双反斜杠(即表示一个)。

使用 new RegExp()的原因之一在于,某些场景中无法事先确定模式,而只能在运行时以字符串方式创建。

参考

参与互动

83.js 中 callee 与 caller 的作用

参考答案:

1.caller 返回一个调用当前函数的引用 如果是由顶层调用的话 则返回 null

(举个栗子哈 caller 给你打电话的人 谁给你打电话了 谁调用了你 很显然是下面 a 函数的执行 只有在打电话的时候你才能知道打电话的人是谁 所以对于函数来说 只有 caller 在函数执行的时候才存在)

var callerTest = function() {
    console.log(callerTest.caller);
};

function a() {
    callerTest();
}
a(); //输出function a() {callerTest();}
callerTest(); //输出null

2.callee 返回一个正在被执行函数的引用 (这里常用来递归匿名函数本身 但是在严格模式下不可行)

callee 是 arguments 对象的一个成员 表示对函数对象本身的引用 它有个 length 属性(代表形参的长度)

var c = function(x, y) {
    console.log(arguments.length, arguments.callee.length, arguments.callee);
};
c(1, 2, 3); //输出3 2 function(x,y) {console.log(arguments.length,arguments.callee.length,arguments.callee)}

参与互动

84.异步加载 js 的方法

参考答案:

方案一: <script> 标签的 async="async"属性(详细参见:script 标签的 async 属性)

点评:HTML5 中新增的属性,Chrome、FF、IE9&IE9+均支持(IE6~8 不支持)。此外,这种方法不能保证脚本按顺序执行。

方案二: <script> 标签的 defer="defer"属性

点评:兼容所有浏览器。此外,这种方法可以确保所有设置 defer 属性的脚本按顺序执行。

方案三:动态创建 <script> 标签

示例:

<!DOCTYPE html>
<html>

<head>
    <script type="text/javascript">
        (function() {
            var s = document.createElement_x("script");
            s.type = "text/javascript";
            s.src = "//code.jquery.com/jquery-1.7.2.min.js";
            var tmp = document.getElementsByTagName_r("script")[0];
            tmp.parentNode.insertBefore(s, tmp);
        })();
    </script>
</head>

<body>
    <img src="//xybtv.com/uploads/allimg/100601/48-100601162913.jpg" />
</body>

</html>

点评:兼容所有浏览器。

方案四:AJAX eval(使用 AJAX 得到脚本内容,然后通过 eval_r(xmlhttp.responseText)来运行脚本)

点评:兼容所有浏览器。

方案五:iframe 方式(这里可以参照:iframe 异步加载技术及性能 中关于 Meboo 的部分)

点评:兼容所有浏览器。

参与互动

85.去除数组重复成员的方法

参考答案:

方法 1 扩展运算符和 Set 结构相结合,就可以去除数组的重复成员

// 去除数组的重复成员
[...new Set([1, 2, 2, 3, 4, 5, 5])];
// [1, 2, 3, 4, 5]

方法 2

function dedupe(array) {
    return Array.from(new Set(array));
}
dedupe([1, 1, 2, 3]); // [1, 2, 3]

方法 3(ES5)

function unique(arry) {
    const temp = [];
    arry.forEach(e => {
        if (temp.indexOf(e) == -1) {
            temp.push(e);
        }
    });

    return temp;
}

参与互动

86.去除字符串里面的重复字符

参考答案:

最简单的方式

[...new Set("ababbc")].join(""); // "abc"

参与互动

87.求数组的最大值

参考答案:Math.max.apply(null, 数组)

var a = [1, 2, 3, 5];
alert(Math.max.apply(null, a)); //最大值
alert(Math.min.apply(null, a)); //最小值

参与互动

88.JS 中 文档碎片的理解和使用

参考答案:

// 1、什么是文档碎片?

document.createDocumentFragment(); // 一个容器,用于暂时存放创建的dom元素

// 2、文档碎片有什么用?

// 将需要添加的大量元素,先添加到文档碎片中,再将文档碎片添加到需要插入的位置,大大 减少dom操作,提高性能(IE和火狐比较明显)

解析:

// 普通方式:(操作了100次dom)
for (var i = 100; i > 0; i--) {
    var elem = document.createElement("div");
    document.body.appendChild(elem); //放到body中
}

//  文档碎片:(操作1次dom)
var df = document.createDocumentFragment();
for (var i = 100; i > 0; i--) {
    var elem = document.createElement("div");
    df.appendChild(elem);
}
//最后放入到页面上
document.body.appendChild(df);

参与互动

89.原型的作用 以及什么是原型

参考答案:作用:实现资源共享

什么是原型: 实例在被创建的那一刻,构造函数的 prototype 属性的值。

参与互动

90.javascript 里面的继承怎么实现,如何避免原型链上面的对象共享

参考答案:用构造函数和原型链的混合模式去实现继承,避免对象共享可以参考经典的 extend()函数,很多前端框架都有封装的,就是用一个空函数当做中间变量

参与互动

91.简单介绍下 JS 的原型和原型链

参考答案:

参与互动

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注