1.储存了某个数据到 localStorage,立即进行 localStorage.getItem,能否取到值?
如果您已经成功将数据存储到 localStorage
中,调用 localStorage.getItem
方法可以立即取出对应的值。举个例子,如果您使用以下代码将一个键值对存储到 localStorage
中:
localStorage.setItem('key', 'value');
那么您可以立即使用以下代码从 localStorage
中获取该键对应的值:
const value = localStorage.getItem('key'); console.log(value); // 输出 "value"
当然,在某些情况下(例如浏览器隐私模式下或者被禁用了 localStorage
功能等),调用 localStorage.getItem
方法可能无法取到值,请确保您的代码在适当的环境下运行。
2.实现异步的方式有几种
在 JavaScript 中,实现异步的方式有以下几种:
1. 回调函数:在函数内部执行异步操作,然后将异步操作的结果作为参数传递到回调函数中。
function doAsyncTask(data, callback) { setTimeout(function() { const result = data.toUpperCase(); callback(result); }, 1000); } doAsyncTask('hello', function(result) { console.log(result); // 'HELLO' });
回调函数的方式非常常见,但也很容易导致回调地狱和可读性问题。
2. Promise:Promise 为一种更加优雅的异步模式,可以更好地解决回调地狱和可读性问题。
function doAsyncTask(data) { return new Promise(function(resolve, reject) { setTimeout(function() { if (data) { const result = data.toUpperCase(); resolve(result); } else { reject(new Error('Data is null')); } }, 1000); }); } doAsyncTask('hello') .then(function(result) { console.log(result); // 'HELLO' }) .catch(function(error) { console.error(error); });
3. Async/Await:Async/Await 是 ES2017 的新增语法,它是基于 Promise 的封装,可以更加方便地编写异步代码,解决了 Promise 的then方法链式调用的可读性问题。
async function main() { try { const result = await doAsyncTask('hello'); console.log(result); // 'HELLO' } catch (error) { console.error(error); } } main();
上述三种方式都可以实现异步,具有不同的特点。回调函数是传统方式, Promise 可以更好的处理 Promise 的嵌套和 then 方法的链式调用问题,Async/Await 则提供了更加优雅的方式,在可读性和维护性方面更加友好。
3.异步不阻塞
异步不阻塞是指当一个异步操作被触发时,它会在后台执行(非主线程中执行),在等待操作完成的同时,主线程可以继续执行其他代码,不会被该异步操作所阻塞。
在 JavaScript 中,异步操作通常使用回调函数、Promise 对象或 async/await 语法来实现。例如,以下代码使用 Promise 对象实现了一个异步操作:
function asyncOperation() { return new Promise((resolve, reject) => { // 模拟一个异步操作 setTimeout(() => { resolve('异步操作完成'); }, 1000); }); } console.log('异步操作执行前'); asyncOperation().then((result) => { console.log(result); }); console.log('异步操作执行后');
在上面的示例中,当程序执行到 console.log('异步操作执行前')
时会首先输出该语句,然后立即执行下一行代码 asyncOperation()
,该函数返回一个 Promise 对象,这个 Promise 对象被 resolve 后继续执行后面的 then 方法中的回调函数,并输出 '异步操作完成'
,最后输出 '异步操作执行后'
。
因此,异步操作的执行不会阻塞主线程的代码,而是后台执行,等待异步操作完成后再去执行相应的回调函数或 Promise 对象的 then 方法中的回调函数。
4.选择 div 的第二个子元素
您可以使用以下 CSS 选择器来选择 div 的第二个子元素:
div:nth-child(2)
在这个选择器中,div
表示选择所有的 div 元素,nth-child(2)
表示选择 div 的第二个子元素。注意,这里的计数不是从 0 开始的,而是从 1 开始的。
以下是一个示例,展示如何使用此选择器选择 div 的第二个子元素,并设置其背景颜色为红色:
<div> <p>第一个子元素</p> <p>第二个子元素</p> <p>第三个子元素</p> </div>
div:nth-child(2) { background-color: red; }
在上面的示例中,第二个
元素的背景颜色将变为红色。
5.display: none 和 visibility: hidden 的区别
display: none
和 visibility: hidden
二者都可以用来隐藏元素,但它们的实现方式和效果略有不同:
display: none
:该样式会将元素完全隐藏,不占据页面布局,也不会响应用户事件(例如点击、鼠标移入等)。设置元素的display
属性为none
会将该元素从渲染树中移除,因此该元素及其所有后代元素在页面上不会被显示,且不占用绘制资源和空间。visibility: hidden
:该样式会使元素隐藏,但在页面布局中仍占据空间,并继续响应用户事件。而这种方式只是让元素不可见,但是元素仍会被渲染出来,只不过不可见罢了。以至于它仍然对渲染树和布局模型可能产生影响。
下面是一个示例,展示 display: none
和 visibility: hidden
的效果差异:
<div> <p>文本内容</p> <button>按钮</button> </div>
div { width: 200px; height: 200px; background-color: #ccc; display: flex; justify-content: center; } p { font-size: 24px; display: none; } button { font-size: 18px; visibility: hidden; }
在上面的示例中,p
和 button
元素分别被设置为 display: none
和 visibility: hidden
。当浏览器渲染页面时,p
元素被完全移除了,因此页面上不会看到任何文本内容,而 button
元素虽然占据了页面的空间,但是在页面上不可见,以至于它不会响应用户事件,即使用户点击了该区域。
因此,一般情况下,如果需要完全删除某个元素,不想再让它占据空间或影响其他元素,应该使用 display: none
,如果只需要将元素隐藏起来,但仍占据空间并继续响应事件,可以使用 visibility: hidden
。
6.如果想要让一个元素的宽高包含元素的 boder 和 padding
| < - a - > | b: 50px | < - c - > |,a 和 c 等比填充,用 flex 怎么实现;如果我想让它变成垂直方向,怎么做?
可以使用 box-sizing
属性来解决这个问题。将 box-sizing
属性设置为 border-box
可以使元素的宽度和高度包括了 padding 和 border,而不用再考虑它们的影响。
对于您的要求,假设父元素宽度已经确定,如果要让其中的子元素宽度和高度等比例填充,可以将父元素的 display
属性设置为 flex
,并在子元素上使用一个占比为 1 的 Flexbox 布局框架。然后将子元素的 box-sizing
属性设置为 border-box
即可。示例代码如下:
<div class="parent"> <div class="child"></div> </div> • 1 • 2 • 3
.parent { display: flex; justify-content: center; align-items: center; width: 200px; height: 200px; border: 10px solid #ccc; padding: 20px; } .child { flex: 1; box-sizing: border-box; background: #f00; }
在上面的示例中,父元素 .parent
的宽度为 200px
,高度为 200px
,同时设置了边框和内边距。子元素 .child
使用了 Flexbox 布局的占比为 1 的框架,在 box-sizing
属性设置为 border-box
之后,它的实际宽度和高度就会考虑到父元素的边框和内边距。
如果希望这个布局框架垂直方向上往下延伸,只需将 .parent
和 .child
元素都添加上 flex-direction: column
属性,示例代码如下:
.parent { display: flex; justify-content: center; align-items: center; width: 200px; height: 200px; border: 10px solid #ccc; padding: 20px; flex-direction: column; } .child { flex: 1; box-sizing: border-box; background: #f00; }
你的前端技术是否能通过这些高频面试题?(二)https://developer.aliyun.com/article/1426321