专栏首页前端笔记本记录一些前端面试题

记录一些前端面试题

写一段脚本,实现:当页面上任意一个链接被点击的时候,alert出这个链接在页面上的顺序号,如第一个链接则alert(1),依次类推。

var links = document.getElementsByTagName('a');
console.log(links);
for (var i = 0; i < links.length; i++) {
    links[i].onclick = (function (i) {
        return function () {
            alert(i)
        }
    })(i)
}
//or
var links = document.getElementsByTagName('a');
console.log(links);
for (let i = 0; i < links.length; i++) {
    links[i].onclick = function (i) {
        alert(i)
    }
}

创建”内置”方法:给String对象定义一个repeatify方法,该方法接收一个整数参数,作为字符串重复的次数,最后返回重复指定次数的字符串。

String.prototype.repeatify = function (num) {
    var str = "";
    for (var i = 0; i < num; i++) {
        str += this;
    }
    return str;
}
console.log("laoxie".repeatify(4))

完成一个函数,接受数组作为参数,数组元素为整数或者数组,数组元素包含整数或数组,函数返回扁平化后的数组,如:[1,[2,[[3,4],5],6]] = > [1,2,3,4,5,6]。

var arr = [1, [2, 3, [4, 5, [6]]], 7];
var newArr = [];

function getNewArr(arr) {
    for (var i = 0; i < arr.length; i++) {
        if (typeof arr[i] == "number") {
            newArr.push(arr[i])
        } else {
            getNewArr(arr[i])
        }
    }
}
getNewArr(arr)

假设现有一篇文章 var content = “…大量文字”,文章触及到一些敏感词[“wscat”,“yao”,“eno”,“6.1”]等,如何在文章中发现这些敏感词,并将背景置为红色或改变字体颜色标识出来。

var str = "6.1号,这是愉快的儿童节,我清晰地记得,愚蠢的yao牵着可爱的eno...";
var keyword = ["老谢", "老蓝", "lemon", "6.1"];
for (var i = 0; i < keyword.length; i++) {
    str = str.split(keyword[i]);
    str = str.join("<span style='color:red'>" + keyword[i] + "</span>")
    console.log(str)
}
document.getElementById('str').innerHTML = str;

不能使用定时器,实现5s刷新一次页面

定时自动刷新,content表示刷新间隔,单位为秒s,下面代码表示页面每隔三秒刷新一次

<meta http-equiv="refresh" content="3">

这种方法实现页面刷新有点投机取巧,这个标签作用是定时跳转,content第一个参数表示间隔时间,单位为秒,第二个参数表示目标网址,但是如果把第二个参数设为#,就会实现页面刷新

<meta http-equiv="refresh" content="3;url=#">

event.currentTarget和event.target的不同

可以发现,由于事件捕获和事件冒泡的存在,很多时候注册的事件监听者event.currentTarget并不是事件的触发者event.target,大部分时候事件可能是由子元素触发的,但是在捕获、冒泡的过程中被父级元素的事件监听器获取到了,注册监听事件的父级元素就是这种情况下event.currentTarget,而事件触发者也就是子元素就是event.target

<head>
    <meta charset="utf-8">
    <title>菜鸟教程(runoob.com)</title>
</head>
<body>
    <p>该实例使用 addEventListener() 方法在按钮中添加点击事件。 </p>
    <button id="myBtn">点我</button>
    <p id="demo"></p>
    <script>
        var btn = document.getElementById("myBtn");
        btn.addEventListener("click", function displayDate1(e) {
            console.log('按钮注册点击事件');
            console.log("e.currentTarget", e.currentTarget);
            console.log("e.target", e.target);
            console.log("this", this)
        });
        document.body.addEventListener("click", function displayDate1(e) {
            console.log('body注册点击事件');
            console.log("e.currentTarget", e.currentTarget);
            console.log("e.target", e.target);
            console.log("this", this)
        });
    </script>
</body>
</html>

css加载会阻塞DOM树渲染吗?

不会

  • css加载不会阻塞DOM树的解析
  • css加载会阻塞DOM树的渲染
  • css加载会阻塞后面js语句的执行

这可能也是浏览器的一种优化机制。因为你加载css的时候,可能会修改下面DOM节点的样式,如果css加载不阻塞DOM树渲染的话,那么当css加载完之后,DOM树可能又得重新重绘或者回流了,这就造成了一些没有必要的损耗。所以我干脆就先把DOM树的结构先解析完,把可以做的工作做完,然后等你css加载完之后,在根据最终的样式来渲染DOM树,这种做法性能方面确实会比较好一点,摘自css加载会造成阻塞吗?

defer和async的区别

<script src="script.js"></script>

没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。

<script async src="script.js"></script>

有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。

<script defer src="myscript.js"></script>

有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。defer和async的区别

遍历一个某一元素下的所有子元素(包括子元素的子元素)的方法,打印出所有子元素的ID

假设要遍历document.body

var allNodes = [];
function getChildNode(node) {
    //先找到子结点
    var nodeList = node.childNodes;
    for (var i = 0; i < nodeList.length; i++) {
        //childNode获取到到的节点包含了各种类型的节点
        //但是我们只需要元素节点  通过nodeType去判断当前的这个节点是不是元素节点
        var childNode = nodeList[i];
        //判断是否是元素结点
        if (childNode.nodeType == 1) {
            console.log(childNode.id);
            allNodes.push[childNode];
            //childNode.style.border = "1px solid red";
            getChildNode(childNode);
        }
    }
}
getChildNode(document.body);
//getChildNode("某元素");

f(1)=1, f(1)(2)=2, f(1)(2)(3)=6, 设置一个函数输出一下的值

难点:打印和相加计算,会分别调用toStringvalueOf函数,所以我们重写temp的toStringvalueOf方法,返回a的值,这里测试的时候发现只要改写toString就可以了

function add(a) {
    var temp = function (b) {
        return add(a + b);
    }
    temp.valueOf = temp.toString = function () {
        return a;
    };
    return temp;
}
console.log(add(1)(2));
alert(add(1)(2)(3));

简单讲,在对对象(广义的,包括函数对象)进行+ - * / == > < >= <=运算时,会依次尝试调用私有toString私有valueOf原型toString原型valueOf,直到遇到返回基本类型(如数字或字符串)停止,这里可以参考实现语法的功能:var a = add(1)(2)(3); //6没看懂别人的代码

var temp = function () {
    var a = 1 + 2;//这里执行了加法所以会执行temp.toString方法
    return temp;
};
temp.toString = function () {
    return "wscats";
};
console.log(temp());

从图片可以看出来,当改写了toString后,既返回了函数,还打印出了结果 <img width="223" alt="2018-11-21 3 36 34" src="https://user-images.githubusercontent.com/17243165/48826109-6e8db400-eda4-11e8-9126-86ad38df62a2.png">

实现下面的函数new Test("test").firstSleep(3).sleep(5).eat("dinner")

具体可以参考链式调用

function Test(name) {
    this.task = [];
    let fn = () => {
        console.log(name);
        this.next();
    }
    this.task.push(fn);
    setTimeout(() => {
        this.next();
    }, 0)
    return this;
}

Test.prototype.firstSleep = function (timer) {
    console.time("firstSleep")
    let that = this;
    let fn = () => {
        setTimeout(() => {
            console.timeEnd("firstSleep");
            that.next();
        }, timer * 1000)
    }
    this.task.unshift(fn);
    return this;
}

Test.prototype.sleep = function (timer) {
    console.time("sleep")
    let that = this;
    let fn = () => {
        setTimeout(() => {
            console.timeEnd("sleep");
            that.next();
        }, timer * 1000)
    }
    this.task.push(fn);
    return this;
}

Test.prototype.eat = function (dinner) {
    let that = this;
    let fn = () => {
        console.log(dinner);
        that.next();
    }
    this.task.push(fn);
    return this;
}

Test.prototype.next = function (dinner) {
    let fn = this.task.shift();
    fn && fn()
}

new Test("test").firstSleep(3).sleep(5).eat("dinner")

如何优化if...else语句

决策树和卫语句

const a = 3;  
//bad:
if (a === 1) {
    console.log('a > 1');
}
if (a === 2) {
    console.log('a > 2');
}
if (a === 3) {
    console.log('a > 3');
}
if (a === 4) {
    console.log('a > 4');
}
// good:
switch(a) {
    case 1:
        console.log('a = 1');
    case 2:
        console.log('a = 2');
    case 3:
        console.log('a = 3');
    defaut:
        console.log('blablabla');
}
const judgeMap = {
    1: () => { console.log('a = 1') },
    2: () => { console.log('a = 2') },
    3: () => { console.log('a = 3') },
    4: () => { console.log('a = 4') }
}
judgeMap[a]();

三元表达式

const strength = (password.length > 7) ? 'Strong' : 'Weak';

position:sticky

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 用键盘8个键演奏一首蒲公英的约定

    用键盘8个键演奏一首蒲公英的约定送给996的自己或月亮代表我的心给七夕的她,非常简单~

    enoyo
  • 我如何用最简单的前端技术揭示那些灰色产业背后的原理

    这篇文章讲述的一些很通用简单的前端技术,但却是实现某些灰色产业的关键技术,当然我只实现一些很简单的思路和方法,尽量写得简单明了,希望能举一反三,一起探索前端技术...

    enoyo
  • Vue3.0 新特性全面探索 - 基于 Composition Api 快速构建实战项目

    建议配合 Visual Studio Code 和 Vue 3 Snippets 代码插件食用Ψ( ̄∀ ̄)Ψ。

    enoyo
  • JavaScript从初级往高级走系列————异步

    上面这个例子中,当执行了alert(1),如果用户不点击确定按钮,console.log(2)是不会执行的。

    FinGet
  • 中高级前端高频面试题分享

    代码比较简单,我们只是在setTimeout的方法里面又调用了一次setTimeout,就可以达到间歇调用的目的。

    前端迷
  • JS面向对象笔记二

    注意点:当构造函数里面有return关键字时,如果返回的是非对象,new命令会忽略返回的信息,最后返回时构造之后的this对象;   如果return返回的是与...

    tandaxia
  • [第13期] 掌握前端面试基础系列一: ES6

    这里我们可以看到, 第一行中的a虽然还没声明, 但是我们用起来却不会报错。这种情况, 就是变量声明的提升。

    用户6900878
  • 横扫 JS 面试核心考点

    Javascript是前端面试的重点,本文重点梳理下Javascript中的常考知识点,然后就一些容易出现的题目进行解析。限于文章的篇幅,无法将知识点讲解的面面...

    grain先森
  • 【面试】386- JavaScript 面试 20 个核心考点

    Javascript是前端面试的重点,本文重点梳理下 Javascript 中的常考基础知识点,然后就一些容易出现的题目进行解析。限于文章的篇幅,无法将知识点讲...

    pingan8787
  • 06JavaScript作用域与对象

    即使我们在定义这个函数之前调用它,函数仍然可以工作。这是因为在 JavaScript 中执行上下文的工作方式造成的。

    Dreamy.TZK

扫码关注云+社区

领取腾讯云代金券