img
的 alt
属性有什么用?当图片加载失败没法看到时,页面会显示alt
属性提供的信息。alt
属性是用于描述图片信息的,那些装饰性的图片除外,这些图片的 alt
信息应该置空。css
善意:html
alt
应该为 ''
Web crawlers
网络爬虫使用 alt
标签识别图片内容,所以这些属性对 Search Engine Optimization (SEO)
搜索引擎优化很重要alt
标签后加.
提升可访问性CSS BEM
是什么?BEM
方法是CSS
类名的命名约定,目的是经过定义命名空间,使 CSS
更易于维护,解决类(class
)的范围问题 。BEM
即 Block Element Modifier
—— 块元素修饰符。 Block
是一个独立的部分,它能够在项目里重复利用并为子元素(Element
)充当命名空间。当一个块或元素在某个状态或者结构样式不一样时,Modifier
能够用做标识符区别这些状态或差别。数据库
/* block component */ .block { } /* element */ .block__element { } /* modifier */ .block__element--modifier { }
这是一个类名标记的例子:编程
<nav class="navbar"> <a href="/" class="navbar__link navbar__link--active"></a> <a href="/" class="navbar__link"></a> <a href="/" class="navbar__link"></a> </nav>
在上例中,navbar
是 Block
,navbar__link
元素 除了是 navbar
组件外没任何意义, navbar__link--active
是一个修饰符, 表示 navbar————link
元素的一种不一样的状态。数组
因为修饰符过于冗长,更多状况下是使用 is-*
标识promise
<a href="/" class="navbar__link is-active"></a>
这些必须与元素连接不能独立使用,不然就会有范围问题。浏览器
.navbar__link.is-active { }
善意:缓存
CSS-in-JS
范围问题:
CSS
只有一个全局命名空间。 在非平凡的应用程序中不可能避免选择器冲突。
cache busting
的用途以及如何实现cache busting
——我暂时不知道如何翻译,大体就是解决缓存文件不刷新问题服务器
浏览器有一个缓存机制来临时存储网站上的文件,因此在页面之间切换或从新加载相同的页面时,这些文件不须要被从新下载。服务器被设置为发送报头,报头告诉浏览器在给定的时间内存储文件。这大大提升了网站的速度,并保持了带宽。网络
可是,当开发人员更改了网站,由于用户的缓存仍然引用旧文件,这可能会致使问题。若是缓存的CSS和JavaScript文件引用的元素已不复存在、已移动或已重命名,则会使它们保留原有功能,或破坏网站。
cache busting
是一种强制浏览器下载新文件的方式,经过将文件命名为与旧文件不一样的名称来实现。
有一种强制浏览器从新下载文件的常见的方式是在文件名称末尾添加一个索引字符串
src="js/script.js" => src="js/script.js?v=2"
这种方式浏览器会将它视做不一样的文件,而且不用重命名文件。
CSS
预处理器的好处是什么?CSS预处理程序添加了本地CSS没有的有用功能,一般经过启用DRY(不要重复)原则使CSS更整洁、更易于维护。它们用于嵌套选择器的简洁语法减小了重复代码。它们为一致的主题化提供了变量(然而,CSS变量已经在很大程度上取代了这个功能),并提供了额外的工具,如color函数(变亮、变暗、透明等)、mixin和循环,这些工具使CSS更像一种真正的编程语言,并使开发人员有更多的能力生成复杂的CSS。
善意:
css
代码CSS
预处理器的缺点: 安装,从新编译耗时等==
与 ===
的区别(===)
检查严格的相等性,这意味着类型和值必须相同。另外一方面,(==)
首先执行类型强制转换,使两个操做数具备相同的类型,而后应用严格的比较。
善意:
===
来测试等式,由于松散等式==
可能会获得不直观的结果。col-{n} / 12
的比例<div class="row"> <div class="col-2"></div> <div class="col-7"></div> <div class="col-3"></div> </div>
设置 .row
的父元素display: flex
;使用flex
的 简写属性 给列类设置一个 与它的比例对应的 flex-grow
值
.row { display: flex; } .col-2 { flex: 2; } .col-7 { flex: 7; } .col-3 { flex: 3; }
<header>
元素么? <footer>
呢?二者均可以。W3文档声明标记表示其最近祖先“部分”的页眉(<header>
)和页脚(<footer>
)区域。所以,不只页面<body>
能够包含页眉和页脚,并且每一个<article>
和<section>
元素也能够包含页眉和页脚。
善意:
<header>
, <article>
,<section>
, <footer>
<header>
用于包含关于页面某个部分的介绍和导航信息。这能够包括章节标题、做者姓名、出版时间和日期、目录或其余导航信息。<article>
是一个自包含的组合,逻辑上能够在页面以外独立地从新建立,而不会失去它的意义。我的博客文章或新闻故事就是很好的例子。<section>
是一个灵活的容器,用于保存具备相同信息主题或目的的内容。<footer>
用于保存应该出如今内容部分末尾的信息,并包含关于该部分的附加信息。做者姓名、版权信息和相关连接就是此类内容的典型例子。善意:
<form>
和<table
>@media
属性的四种类型吗?all
适用于全部媒体类型的设备print
它只适用于打印机screen
仅适用于屏幕(台式机、平板电脑、手机等)speech
这只适用于屏幕阅读器const a = [1, 2, 3] const b = [1, 2, 3] const c = "1,2,3" console.log(a == c) console.log(a == b)
第一个console.log
输出true
,由于JavaScript
的编译器执行类型转换,所以它根据字符串的值与字符串进行比较。另外一方面,第二个console.log
输出false
,由于数组是对象,对象经过引用进行比较(比较的是内存地址)。
善意之言:
null, undefined, number, string, boolean
)数据的值rel="noopener"
的使用情景和使用目的rel="noopener"
是<a>
元素(超连接)中使用的一个属性。它防止页面拥有window.opener
属性,这个属性指向原来的的页面,并容许从超连接打开的页面操做超连接所在的页面,即新打开的页面控制原来跳转页。务必在target='_blank'
后加上此属性,兼容火狐写法rel="noopener norefferrer"
善意之言
rel=“noopener”
应用于超连接。rel="noopener"
防止打开的连接操做源页面。JavaScript
的自动分号插入(ASI)下列代码输出什么?
function greet() { return { message: "hello" } }
undefined
因为 JavaScript
的自动分号插入机制 automatic semicolon insertion
(ASI), 编译器在return
关键字后放置分号,所以它返回undefined
,不会抛出错误。
善意之言:
null
和undefined
之间的区别是什么?在JavaScript
中,两个值分别表示空
——undefined
和null
。它们之间的具体区别是null
是显式的,而undefined
是隐式的。当属性不存在或变量没有被赋予值时,该值是undefined
。设置值null
是显式地指示“no value”。在本质上,undefined
用于空
未知的状况,null用于空
已知的状况。也就是说,变量只声明不知道它指代什么时,也就是说它是未知的,是undefined
,若变量已知,但在一些时候是没有内容的,则用null
赋值
善意之言:
typeof undefined
的值为“undefined”
。typeof null
计算“object
”。然而,它仍然是一个原始值,这在JavaScript
中被认为是一个实现错误。undefined == null
的值为true。MIME
类型是什么?它的用途是什么?MIME
是Multi-purpose Internet Mail Extensions
的缩写。它是用做在Internet
上对文件类型进行分类的标准方法。
善意之言:
MIME type
实际上有两个部分:一个类型和一个用斜杠(/)分隔的子类型。例如,Microsoft Word
文件的MIME
类型是application/msword
(类型为application
,子类型为msword
)。typeof
的运算结果求下列代码的值
typeof typeof 0
输出: "string"
先获得 0的类型"number"
, 而后 typeof "number"
得出 "string"
typeof
操做符返回一个
字符串表示未鉴定的操做数的类型
JavaScript
的数据类型最新的 ECMAScript
标准定义了七种数据类型,六种基本/原始数据类型:Boolean, Null, Undefined, Number, String, Symbol
,以及一种非原始数据类型: Object
.
对以上数据类型使用 typeof
(结果都是小写): boolean
, object, undefined
, number
, string
, symbol
, object
善意之言
Symbol
Array, Date and Function
都是 object
对象类型(typeof 函数的出来function
)JavaScript
中的函数是能被调用的对象判断类型:
object instanceof constructor
instanceof
运算符用来检测constructor.prototype
是否存在于参数object
的原型链上。
parameter
和 arguments
的区别参数Parameter
是函数定义时形参的变量名,而arguments
是函数调用时给定的值
function myFunction(parameter1, parameter2) { console.log(arguments[0]) // "argument1" } myFunction("argument1", "argument2")
友情提示
arguments
是一个类数组对象,包含了函数触发调用时获得的参数信息myFunction.length
只表示函数的参数数量(本例中为2
),不管函数调用时传入多少参数示例以下
function myFunction(parameter1, parameter2) { console.log(myFunction.length) //2 console.log(arguments[2]) // "3" 这里虽然函数只接受两个参数,但调用时传了多的两个`3,4`在arguments中也取到了 } console.log(myFunction.length) // 2 myFunction("argument1", "argument2", 3, 4)
maskCahr
屏蔽除最后count
为以外的字符mask("123456789") // "#####6789"
有不少方法解决:
使用 String.prototype.slice()
传入参数-4
获取字符串最后 4
位字符 ,而后用 String.prototype.padStart()
传入字符串长度和 替换符号 把字符串用 指定符号填充至 指定长度.
const mask = (str, maskChar = "#") => str.slice(-4).padStart(str.length, maskChar)
善意之言
recursion
是什么 ? 何时用?递归是一个过程的重复应用。在JavaScript
中,递归涉及不断调用自身的函数,直到它们达到一个基本条件。基本条件打破递归循环,不然函数将无限递归循环下去。当处理嵌套若干层的数据时递归很是有用。
例如,有一个数据库返回的一系列评论,它存在于一个平面数组中,可是须要嵌套以在UI中显示。每一个注释要么是顶级注释(没有父注释),要么是对父注释的回复。评论能够是回复的回复,回复的回复…咱们事先不知道一个评论可能有多少层深度。这就是递归能够提供帮助的地方。
const nest = (items, id = null, link = "parent_id") => items .filter(item => item[link] === id) .map(item => ({ ...item, children: nest(items, item.id) })) const comments = [ { id: 1, parent_id: null, text: "First reply to post." }, { id: 2, parent_id: 1, text: "First reply to comment #1." }, { id: 3, parent_id: 1, text: "Second reply to comment #1." }, { id: 4, parent_id: 3, text: "First reply to comment #3." }, { id: 5, parent_id: 4, text: "First reply to comment #4." }, { id: 6, parent_id: null, text: "Second reply to post." } ] nest(comments) /* [ { id: 1, parent_id: null, text: "First reply to post.", children: [...] }, { id: 6, parent_id: null, text: "Second reply to post.", children: [] } ] */
在上例中,基础条件是filter()
返回空数组。链式的map()
不会触发递归调用的回调函数,进而跳出递归循环。
善意提醒:
JavaScript
中惟一不等于自身的值是什么?当与任何比较运算符比较时,NaN
(not -a- number) 是惟一不等于自身的值。NaN
一般是没有意义的数学计算的结果,因此两个NaN
值被认为相等没有意义。
善意提醒
isNaN()
和Number.isNaN()
的区别
//isNaN console.log(isNaN(null)); //false console.log(isNaN(true)); //false console.log(isNaN(false)); //false console.log(isNaN(0)); //false console.log(isNaN(undefined)); //true console.log(isNaN("AB")); //true console.log(isNaN({a: 1})); //true console.log(isNaN(NaN)); //true //Number.isNaN console.log(Number.isNaN(null)); //false console.log(Number.isNaN(true)); //false console.log(Number.isNaN(false)); //false console.log(Number.isNaN(0)); //false console.log(Number.isNaN(undefined)); //false console.log(Number.isNaN("AB")); //false console.log(Number.isNaN({a: 1})); //false console.log(Number.isNaN(NaN)); //true
const isNaN = x => x !== x
Node.js
中的事件循环是什么?事件循环处理全部异步回调。回调将在循环中排队,而其余代码将运行,并将在收到每一个代码的响应后逐个运行。
善意提醒
Node.js
执行非阻塞I/O操做,尽管JavaScript是单线程的getData(function(a) { getMoreData(a, function(b) { getMoreData(b, function(c) { getMoreData(c, function(d) { getMoreData(d, function(e) { // ... }) }) }) }) })
重构使用返回promise
或者使用 async/await
的函数一般是最好的选择。 它们没有为函数提供致使深度嵌套的回调,而是返回一个能够等待的promise
,而且在数据到达后将被解析,从而容许以相似于同步的方式计算下一行代码。
以上代码能够被重构成这样:
async function asyncAwaitVersion() { const a = await getData() const b = await getMoreData(a) const c = await getMoreData(b) const d = await getMoreData(c) const e = await getMoreData(d) // ... }
有许多方式解决回调地狱的问题:
async
Promise
的生成器async/await
(>es7)善意提醒
闭包是在另外一个函数中定义的函数,即便在其词法做用域以外执行,也能够访问其词法做用域。
闭包能够访问三个范围内的变量:
在JavaScript
中,全部函数都是闭包,由于它们能够访问外部范围,可是大多数函数没有利用闭包的有用性:状态的持久性。闭包有时也所以被称为有状态函数。
此外,闭包是存储没法从JavaScript外部访问的私有数据的惟一方法。它们是UMD (Universal Module Definition)
模式的关键,UMD
模式常常用于只公开公共API但保持实现细节私有的库中,以防止与其余库或用户本身的代码发生名称冲突。
友情提醒:
MDN
的闭包解释,也很清晰