资讯专栏INFORMATION COLUMN

前端面试知识点集锦

iKcamp / 1933人阅读

摘要:个人总结的比较全面的前端面试知识点。主要是一些个人认为面试时容易考到以及平时需要注意的一些知识点。如果需要进行深入了解可以根据知识点查询相关的技术文章。

个人总结的比较全面的前端面试知识点。主要是一些个人认为面试时容易考到以及平时需要注意的一些知识点。

本人只是对这些知识进行了一个大概的总结,还有一部分技术还没开始涉及,后期会持续添加。如果需要进行深入了解可以根据知识点查询相关的技术文章。

本文涵盖了以下各个方面的知识:

HTML, CSS, JS基础知识

网站性能优化知识

前端项目自动化构建相关知识

算法相关知识

网络与HTTP协议相关知识

前端的安全相关知识

插件编写相关知识

JS模块化编程相关知识

Github Repo:
https://github.com/Erichain/Front-End-Interview-Points

持续更新中。欢迎fork和star进行完善。

关于前端是什么,以及需要学习什么,移步这里:

Front-End Developer Handbook

HTML部分 docType

混杂模式

标准模式

准标准模式

标签语义化

去掉或者丢失样式的时候能够让页面呈现出清晰的结构

有利于SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息:爬虫依赖于标签来确定上下文和各个关键字的权重

方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)以意义的方式来渲染网页

便于团队开发和维护,语义化更具可读性,是下一步网页的重要动向,遵循W3C标准的团队都遵循这个标准,可以减少差异化

块级标签,行内标签

块级:div, ul, li, ol, table, th, tbody, tfoot, tr, pre, fieldset, form, h1-6, p等

a, abbr, b, br, code, em, img, input, label, select, textarea, strong等

meta标签

如何在不使用JS的情况下刷新页面(http-equiv="refresh", content="time")

设置页面缓存

移动端设置

etc.

HTML代码优化

标签嵌套层级不要太深,标签尽量简洁化.如懒加载后将data属性去除

大量图片的懒加载策略,以及一些元素利用ajax在onload后实行延迟加载

对一些js的异步加载

搜索引擎优化SEO CSS部分 浮动,清除浮动的方法和原理(4种方法)

使用空标签设置clear: both;

为父级元素设置overflow: hidden;(利用BFC的原理)

使用伪元素,为要清除浮动的元素添加.clearfix类(推荐)

使用min-height: contain-floats;(不推荐,兼容性不好)

CSS块级格式化上下文

触发条件

position属性不为static或者relative

float属性不为none

非块级的块级元素(inline-block, table-cell)

overflow不为visible

特性

内部的Box会在垂直方向,从顶部开始一个接一个地放置

Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生叠加

BFC的区域不会与float box叠加

BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然

计算BFC的高度时,浮动元素也参与计算

用处

解决margin边距叠加问题。为元素多带带创建一个BFC来防止外边距的折叠

布局

清除浮动。为包含浮动元素的container创建BFC来清除浮动

盒子模型(IE盒子模型的区别)

总宽度 = margin+padding+border+content,IE的盒子模型的宽度不计padding和border

css3的box-sizing属性,详见https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing

content-box,border和padding不计算入width之内

border-box,border和padding计算入width之内

定位

定位和浮动的区别

什么时候使用定位,什么时候使用浮动

样式继承

可继承的样式

font-size font-family color text-indent

z-index属性

理解 CSS 的 z-index 属性

IE浏览器的hack

条件hack

属性hack

_ IE6

*+IE7

+IE6/7

.IE8

选择符hack

*IE7

_IE6

CSS sprite

减少请求

布局模型

双飞翼布局

圣杯布局

CSS优先级

行内样式 > 内联样式 > 外部样式,ID > Class > Element

设置了!important的样式优先级更高

Flexbox

A Complete Guide to Flexbox

各个单位的区别(px, em, rem, 百分比)

Understanding Font sizing in CSS: em – px – pt – percent – rem

REM vs EM – The Great Debate

居中

CSS Center Complete

link和@import的区别

link属于XHTML标签,而@import是CSS提供的

页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载

@import只在IE5以上才能识别,而link是XHTML标签,无兼容问题

link方式的样式的权重 高于@import的权重

如何将div与图片设置等宽,inline-block元素之间的空隙如何解决

设置父元素font-size为0,再对里面的文字多带带设置font-size

全兼容的样式解决方法

.finally-solve {
    letter-spacing: -4px; /*根据不同字体字号或许需要做一定的调整*/
    word-spacing: -4px;
    font-size: 0;
}
.finally-solve li {
    font-size: 16px;
    letter-spacing: normal;
    word-spacing: normal;
    display:inline-block;
    *display: inline;
    zoom:1;
}
CSS优化

嵌套层级不要太深,一般三层最多

css解析从右向左,所以最右边的应该是相对少一点

html用了base64的img的话,并不会缓存起来,可以将这个base64的图片放在css文件里,css会缓存,图片就缓存起来了

尽量不用后代元素选择器,最右边的一层不要是标签,尤其是像div这种非常常用的标签

多使用css的继承,而不是每一次都书写时都全部重写一遍。写多个css属性时,能连在一起写的就连在一起写

预处理器

Sass

JS部分 严格模式

"use strict"

不能使用eval()

抑制this的行为

不允许读写evalarguments的值

不允许意外创建全局变量

变量

使用var定义的全局变量不能使用delete删除

无var创建的全局变量可以使用delete删除

隐式类型转换

数字与字符串相加,结果为字符串

数字与字符串相减,结果为数字

比较变量的是否相同时,要采用=====会发生隐式类型转换

NaN与任何变量不相等

类型检测

typeof

instanceof

constructor

Object.prototype.toString.apply()

作用域

全局作用域

函数作用域

对象

hasOwnProperty, isPrototypeOf, propertyIsEnumerable

配置属性(configurable, enumerable, writable, value)

特性

扩展: isExtensible, preventExtensions(是否可以添加新的属性)

密封: isSealed, seal(是否可以删除属性,是否可以配置属性)

冻结: isFrozen, freeze(所有属性是否可读可写)

定义属性

defineProperty, defineProperties

数组

数组的类型检测

数组的方法

slice()

map()

every()

some()

filter()

函数

柯里化

概念:部分求值(Partial Evaluation),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术

function currying( fn ) {
    var args = Array.prototype.slice.call(arguments, 1);
    return function () {
        var newArgs = args.concat(Array.prototype.slice.call(arguments));
        return fn.apply(null, newArgs);
    }
}

arguments对象

JS函数不存在重载,后定义的函数会覆盖先定义的函数

函数调用模式

方法调用

函数调用

构造器调用

apply调用

new操作符的原理

使用new关键字来创建实例的时候,原理如下:

首先,在构造函数内部使用Object.create(constructor.prototype)创建一个对象继承自构造函数

然后,将这个对象引用到this

最后,返回this

闭包

概念

作用

创建匿名执行函数

缓存变量,防止被垃圾回收

实现函数的封装

应用场景

内部函数访问外部函数的变量

使用闭包代替全局变量

封装相关功能

回调函数

创建私有变量和公有变量

特性

经典例子:列表点击,弹出每一个的index

/* 错误做法 */
var elems = document.getElementById("links").getElementsByTagName("li");

for ( var i = 0; i < elems.length; i++ ) {
    elems[i].addEventListener("click", function ( event ) {
        event.preventDefault();
        alert(i);
    }, false);
}
/* 正确的做法,使用闭包 */
var elems = document.getElementById("links").getElementsByTagName("li");

for ( var i = 0; i < elems.length; i++ ) {
    (function ( index ) {
        elems[i].addEventListener("click", function ( event ) {
            event.preventDefault();
            alert(index);
        }, false);
    
    })( i );
}
this

函数的this的值永远绑定在调用此函数的对象上

可以使用applycall或者bind改变this值的指向

对象创建的模式和方法及区别

工厂模式

/* 缺点:无法检测对象的类型 */
var createPerson = function ( name, age, job ) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;

    return o;
};

var person1 = createPerson("Erichain", 21, "Web");

构造函数模式

/* 缺点:每个方法要在每个实例上重新创建一遍 */
var Person = function ( name, age, job ) {
    this.name = name;
    this.age = age;
    this.job = job;
}

var person1 = new Person("Erichain", 21, "Web");

原型模式

var Person = function () {};

Person.prototype = {
    constructor: Person, // 如果这个属性十分重要的话
    name: "Erichain",
    age: 21,
    job: "web"
};
var person1 = new Person();

组合构造函数原型模式

动态原型模式

var Person = function ( name, age, job ) {
    this.name = name;
    this.age = age;
    this.job = job;

    if ( typeof this.sayName !== "function" ) {
        Person.prototype.sayName = function () {
            alert( this.name );
        }
    }
};

寄生构造函数模式

除了使用new来实例化外,与工厂模式没区别

不能依赖instanceof来确定对象类型,一般不建议使用

稳妥构造函数模式

原型和继承

原型链

借用构造函数

function Person( name ) {
    this.name = name;
}

function man() {
    // 继承自Person,可以选择是否传入参数
    Person.call(this, "Erichain");
}

组合继承

原型式继承

寄生式继承

寄生组合式继承

new Object()Object.create()的区别

Object.create创建的对象直接从他的第一个参数继承,而new Object所创建的对象是从对象的原型上继承

使用Object.create,可以创建一个不继承于任何东西的对象,但是,如果设置someConstructor.prototype = null,那么,这个新创建的对象会继承自Object.prototype

回调函数 变量提升,函数声明提升

函数声明优于变量声明

函数声明会覆盖变量声明,但是不会覆盖变量赋值

IIFE(立即执行函数)

在闭包中保存变量状态

模块化

IIFE和自执行函数的区别

IIFE的几种表示方法

(function () {})();
(function () {}());

!function () { /* code */ } ();
~function () { /* code */ } ();
-function () { /* code */ } ();
+function () { /* code */ } ();
事件

事件流

事件捕获

处于目标

事件冒泡

事件对象(IE的区别)

跨浏览器事件处理函数

var EventUtil = {
    getEvent: function ( event ) {
        return event ? event : window.event;
    },
    getTarget: function ( event ) {
        return event.target || event.srcElement;
    },
    addHandler: function ( elem, type, handler ) {
        if ( elem.addEventListener ) {
            elem.addEventListener(type, handler, false);
        }
        else if ( elem.attachEvent ) {
            elem.attachEvent("on" + type, handler);
        }
        else {
            elem["on" + type] = handler;
        }
    },
    preventDefault: function ( event ) {
        if ( event.preventDefault ) {
            event.preventDefault();
        }
        else {
            event.returnValue = false;
        }
    },
    stopPropagation: function ( event ) {
        if ( event.stopPropagation ) {
            event.stopPropagation();
        }
        else {
            event.cancelable = true;
        }
    }
};

事件广播

事件委托

var links = document.getElementById("links");

// 使用之前定义的跨浏览器事件处理程序
EventUtil.addHandler(links, "click", function ( event ) {
    var target = EventUtil.getTarget(event);
    event = EventUtil.getEvent(event);

    switch ( target.id ) {
        case "link1":
            // do something
            break;
        case "link2":
            // do something
            break;
        case "link3":
            // do something
            break;
    }
});

事件函数的参数(注意addEventListener()的最后一个参数,如果为false表示在冒泡阶段获取事件,如果为true,表示在事件捕获阶段获取事件)

call, apply, bind(手动实现)

call(obj, args), apply(obj, array)

callapply支持低版本浏览器,bind只支持高版本浏览器

bind原生代码实现

if ( !Function.prototype.bind ) {
    Function.prototype.bind = function ( oThis ) {
        if ( typeof this !== "function") {
            throw new Error("What is trying to be bound is not callable");
        }

        var aArgs = Array.prototype.slice.call(arguments, 1),
            fToBound = this,
            fNOP = function () {},
            fBound = function () {
                return fToBound.apply(
                    this instanceof fNOP ? this : oThis,
                    aArgs.concat(Array.prototype.slice.call(arguments))
                )
            };

        if ( this.prototype ) {
            fNOP.prototype = this.prototype;
        }

        fBound.prototype = new fNOP();
        return fBound;
    };
}
能力检测 BOM

window对象

location对象

screen对象

navigator对象

检测插件navigator.plugins

检测用户代理navigator.userAgent

history对象

promise

Javascript Promise 迷你书

JavaScript Promise API

DOM 操作

查找

document.getElementById

document.getElementsByTagName

document.getElementsByName

document.getElementsByClassName

document.querySelector

document.querySelectAll

节点关系

element.childNodes

element.firstChild

element.lastChild

element.previousSibling

element.nextSibling

element.parentNode

element.appendChild()

element.insertBefore()

element.removeChild()

element.replaceChild()

属性操作

element.getAttribute()

element.setAttribute()

样式操作

element.style[PROPERTY_NAME]

element.classList

element.classList.add

element.classList.remove

element.classList.contains

element.classList.toggle

元素遍历

childElementCount子元素数量

firstElementChild第一个子元素: firstChild的元素版

lastElementChild最后一个子元素: lastChild的元素版

previousElementSibling->previousSibling的元素版

nextElementSibling->nextSibling的元素版

遍历方法

document.createNodeIterator(root, whatToShow, filter)参见https://developer.mozilla.org/en-US/docs/Web/API/NodeIterator

document.createTreeWalker(root, whatToShow, filter, expandEntityReferences, currentNode)参见https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker

性能优化

操作DOM的时候一定要缓存变量,避免发生大量的重排重绘

异步加载Javascript文件

使用document.write()

动态改变已有script标签的src属性

使用DOM方法动态创建script元素

使用Ajax获取脚本内容再加载

在script标签中使用defer以及async属性

按需加载

合并文件

合理使用二进制

CDN加速,原理

图片懒加载

懒加载——网页图片的加载技术

Lazy Load Plugin for jQuery

预加载

3 Ways to Preload Images with CSS, JavaScript, or Ajax

Prefetching, preloading, prebrowsing

prefetch

HTML5 Prefetch

函数节流

浅谈函数节流

垃圾回收

引用计数

/* 出现循环引用的例子 */
function () {
    var objectA = {},
        objectB = {};

    objectA.someOtherObject = objectB;
    objectB.anotherObject = objectA;
}

标记清除

内存泄漏

setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏

循环引用

优雅降级和渐进增强

优雅降级:Web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,则代码会检查以确认它们是否能正常工作。由于IE独特的盒模型布局问题,针对不同版本的IE的hack实践过优雅降级了,为那些无法支持功能的浏览器增加候选方案,使之在旧式浏览器上以某种形式降级体验却不至于完全失效

渐进增强:从被所有浏览器支持的基本功能开始,逐步地添加那些只有新式浏览器才支持的功能,向页面增加无害于基础浏览器的额外样式和功能的。当浏览器支持时,它们会自动地呈现出来并发挥作用

JSON

JSON.stringify() json序列化为字符串

JSON.parse() 将类JSON的字符串转化为JSON对象

XMLHttpRequest对象

一段比较完整的使用原生Javascript实现ajax请求方法

function createRequestObject() {
    if ( window.XMLHttpRequest ) {
        return new XMLHttpRequest();
    }

    // 针对IE
    else if ( window.ActiveXObject ) {
        return new ActiveXObject("Microsoft.XMLHTTP");
    }
}

// 请求的回调函数
function requestCallBack() {
    if ( request.readyState === 4 && request.status === 200 ) {
        console.log(request.responseText);
    }
}

var request = createRequestObject();

request.onreadystatechange = requestCallBack;
// open函数的三个参数分别是请求的方法, 请求的地址, 是否异步(true表示异步)
request.open("POST", url, true);
request.send(null);
使用Javascript计算两个日期的时间差

JavaScript: DateDiff & DateMeasure: Calculate days, hours, minutes, seconds between two Dates

性能测试工具

Performance Tools

代码审查工具

JSHint

JSLint

ESLint(针对ECMAScript 2015)

代码压缩

JSMin

YUI Compressor

Gzip

Javascript原生函数使用

You-Dont-Need-jQuery

Array.prototype.slice.call()原理

how does Array.prototype.slice.call() work?

RESTful 浏览器部分 各个浏览器内核

IE: Trident

Chrome: Webkit, Blink(now)

Firefox: Gecko

Opera: Presto

sessionStorage,cookie,localStorage

cookie 由服务器生成,可设置失效时间。如果是浏览器端生成的cookie,则在浏览器关闭之后失效;而localStorage除非被清除,否则永久保存,sessionStorage则在关闭浏览器或者页面之后清除

cookie的大小为4k左右,localStorage和sessionStorage的大小一般为5MB

与服务器痛心的时候,cookie每次都会携带在http头中,但是其他两个不参与服务器通信

cookie中最好不要放置任何的明文的东西,其他两个的数据如果提交到服务器一定要校验

浏览器的多个标签页之间如何通信

Javascript communication between browser tabs/windows

关于浏览器缓存

浅谈Web缓存

前端安全

防止XSS(跨站点脚本)攻击

防止CSRF(跨站点伪造请求攻击)

防止跨iframe攻击

自动化 npm与bower的区别

bower与npm的不同点

gulp流与管道的概念

Unix流

管道

管道是一个固定大小的缓冲区

从管道读数据是一次性操作,数据一旦被读,它就从管道中被抛弃,释放空间以便写更多的数据

可以把一个进程的标准输出流与另一个进程的标准输入流连接起来

打包后静态资源路径的修改 gulp和grunt的区别

前端工程的构建工具对比 Gulp vs Grunt

测试工具

Mocha

Karma

Jasmine

网络知识部分 Ajax 同源策略

同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议。 指一段脚本只能读取来自同一来源的窗口和文档的属性

跨域处理(方法和区别)

JSONP

document.domain

window.name

HTML5的window.postMessagewindow.onmessage

HTTP基本知识

前端进阶--让你升级的网络知识

三次握手

客户端发起连接试探

服务端接收到试探请求,向客户端发送确认消息

客户端得到服务端的确认消息之后,再次向服务端发送确认消息

一次完整的http请求是怎么样的

域名解析

TCP三次握手

发起http请求

服务器端响应http请求,客户端得到html代码

浏览器解析html代码,并请求html代码中的资源

浏览器对页面进行渲染呈现给用户

框架相关知识 jQuery

jQuery Tips Everyone Should Know

如何组织jQuery项目的代码结构

Best Practice to Organize Javascript Library & CSS Folder Structure

Bootstrap,插件原理

栅格布局实现原理

.img-responsive实现原理

内联表单实现原理

Bootstrap组件实现原理

AngularJS

双向绑定

$digest循环

dirty checking

$watch

MVC

独立作用域

依赖注入

循环监听

ng-ifng-hide/show的区别

ng-iftrue的时候节点才会存在于DOM中

ng-show/hide只是控制节点的显示和隐藏

factoryserviceprovider的区别和关系

使用factory创建的服务,是一个对象,然后,将方法和属性定义在这个对象上,在返回这个对象,就可以供外部controller调用了

使用service创建的服务,是使用new进行实例化的,所以,方法和属性要定义在this上,并且这个服务会自动返回this

使用provider创建的服务,是唯一可以注入到config()函数的服务,可以用来提供模块化的配置。并且,定义在this上的属性和方法,在config函数里才可以访问,从this.$get()函数里返回的属性和方法,才能被控制器所访问

ng-click是否可以使用原生函数

不可以,因为对应的方法不存在于其控制器中,除非在控制器中声明

ng-repeat数组中有相同元素的解决办法

可以添加track by $index

$emit$broadcast$on

$emit由子级向父级广播,$broadcast由父级向子级广播

controllerAs$scope的区别

AngularJS的缺点

强约束,学习成本高

不利于SEO

性能问题

减少监控项

主动设置索引

降低渲染的数据数量

数据扁平化

算法 数组降维

优雅的数组降维——Javascript中apply方法的妙用

数组去重

最简单的方法

function removeDuplicate( arr ) {
    var len = arr.length,
        temp = [];

    for ( var i = 0; i < len; i+=1 ) {
        if ( temp.indexOf(arr[i]) === -1 ) {
            temp.push(arr[i]);
        }
    }
    return temp;
}
对象深度复制
function clone( Obj ) {   
        var buf;   
        if ( Obj instanceof Array ) {   
            buf = [];  //创建一个空的数组 
            var i = Obj.length;   
            while ( i-- ) {   
                buf[i] = clone(Obj[i]);   
            }   
            return buf;   
        }
        else if ( Obj instanceof Object ) {   
            buf = {};  //创建一个空对象 
            for ( var k in Obj ) {  //为这个对象添加新的属性 
                buf[k] = clone(Obj[k]);   
            }   
            return buf;   
        }
        else {   
            return Obj;   
        }   
    }  
各个类型的复制
function clone( obj ) {
    var dest;
    
    switch( typeof obj ) {
        case "undefined":
            break;
            
        case "number":
            dest = +obj;
            break;
            
        case "string":
            dest = obj + "";
            break;
            
        case "boolean":
            dest = obj;
            break;
        
        case "object":
            if ( obj instanceof Array ) {
                dest = [];

                for ( var i = 0; i < obj.length; i++ ) {
                    dest[i] = obj[i];
                }
            }
            else {
                dest = {};
                for ( var i in obj ) {
                    dest[i] = obj[i];
                }
            }
        
        default:
            break;
    }

    return dest;
}
排序

快速排序

function quickSort( arr ) {
    var left = [],
        right = [],
        len = arr.length,
        breakPoint = arr[0];

    if ( len === 1 || len === 0 ) {
        return arr;
    }

    for ( var i = 1; i < len; i++ ) {
        if ( arr[i] < breakPoint ) {
            left.push(arr[i]);
        }
        else {
            right.push(arr[i]);
        }
    }

    return quickSort(left).concat(breakPoint, quickSort(right));
}

冒泡排序

function bubbleSort( arr ) {
    var len = arr.length,
        temp;

    for ( var i = 0; i < len - 1; i ++ ) {
        for ( var j = 0; j < len - 1 - i; j++ ) {
            if ( arr[j] > arr[j+1] ) {
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }

    return arr;
}

插入排序

function insertSort( arr ) {
    var len = arr.length,
        temp;

    for ( var i = 1; i < len; i++ ) {
        var j;
        temp = arr[i];
        j = i;

        while ( j > 0 && arr[j-1] > temp ) {
            arr[j] = arr[j-1];
            j--;
        }
        arr[j] = temp;
    }
    return arr;
}
去除首尾空格
function removePlace( str ) {
    var reg = /(^s*)|(s*)$/;

    if ( str && typeof str === "string" ) {
        return str.replace(reg, "");
    }
}
统计字符数量
function charCount( str ) {
    var obj = {},
        len = str.length,
        i = 0;

    for ( ; i < len; i++ ) {
        var val = str.charAt(i);

        if ( obj[val] && obj[val].value === val ) {
            obj[val].count++;
        }
        else {
            obj[val] = {};
            obj[val].count = 1;
            obj[val].value = val;
        }
    }

    for ( var key in obj ) {
        console.log( key + " is " + obj[key].count );
    }

    return obj;
}
插件编写

关于插件编写,可参考:jQuery插件库

焦点轮播图 弹窗效果 多级菜单 tab切换 Lightbox Javascript模块化 CommonJS

同步的方式加载模块,服务器优先

使用require加载模块,使用module.exports定义模块

AMD

浏览器优先的方式,通过异步加载的方式完成任务

使用define(["module"], function ( module ) {})加载模块

不兼容 io、文件系统(filesystem)和其它通过 CommonJS 实现的面向服务器的功能

推崇依赖前置

对于依赖的模块提前执行

CMD

推崇依赖就近

对于依赖的模块延迟执行

使用define(function ( require, exports, module ) {})加载模块

UMD(通用模块定义,Universal Module Definition)

同时支持 AMD 和 CommonJS 特性

Javascript设计模式

Learning JavaScript Design Patterns

NodeJS HTML5 CSS3 Websocket Canvas

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/115205.html

相关文章

  • 「大集锦」WEB前端开发 辨析类 面试真题

    摘要:学堂码匠面试里最常出现的问题句式大概就是说说和的区别谈谈和的不同了吧一波波的辨析题正在袭来,快快开启防御,杀出重围,来一场绝地反击僵尸,啊,不对,辨析三连发扫描了众多的面试题,发现额各个技术之间的辨析真的是如僵尸一般,一波一波的相信不少人 HTML5学堂-码匠:面试里最常出现的问题句式大概就是说说XXX和XXX的区别谈谈XXX和XXX的不同了吧~!一波波的辨析题正在袭来,快快开启防御,...

    CoderStudy 评论0 收藏0
  • 「大集锦」WEB前端开发 辨析类 面试真题

    摘要:学堂码匠面试里最常出现的问题句式大概就是说说和的区别谈谈和的不同了吧一波波的辨析题正在袭来,快快开启防御,杀出重围,来一场绝地反击僵尸,啊,不对,辨析三连发扫描了众多的面试题,发现额各个技术之间的辨析真的是如僵尸一般,一波一波的相信不少人 HTML5学堂-码匠:面试里最常出现的问题句式大概就是说说XXX和XXX的区别谈谈XXX和XXX的不同了吧~!一波波的辨析题正在袭来,快快开启防御,...

    ralap 评论0 收藏0
  • 「大集锦」WEB前端开发 辨析类 面试真题

    摘要:学堂码匠面试里最常出现的问题句式大概就是说说和的区别谈谈和的不同了吧一波波的辨析题正在袭来,快快开启防御,杀出重围,来一场绝地反击僵尸,啊,不对,辨析三连发扫描了众多的面试题,发现额各个技术之间的辨析真的是如僵尸一般,一波一波的相信不少人 HTML5学堂-码匠:面试里最常出现的问题句式大概就是说说XXX和XXX的区别谈谈XXX和XXX的不同了吧~!一波波的辨析题正在袭来,快快开启防御,...

    vincent_xyb 评论0 收藏0
  • #yyds干货盘点# 前端基础知识面试集锦1

    摘要:作用标准模式与兼容模式各有什么区别声明位于位于文档中的第一行,处于标签之前。又称内核及以上版本,等内核及以上。存储大小数据大小不能超过。可以防止恶意刷票论坛灌水有效防止对某一个特定注册用户用特定程序暴力方式进行不断的登陆尝试。 HTMLDoctype作用?标准模式与兼容模式各有什么区别?(1)、声明位于位于HT...

    番茄西红柿 评论0 收藏2637

发表评论

0条评论

iKcamp

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<