侧边栏壁纸
博主头像
前端江太公博主等级

不知江月待何人

  • 累计撰写 178 篇文章
  • 累计创建 3 个标签
  • 累计收到 127 条评论
标签搜索

目 录CONTENT

文章目录

面试题总结(1).md

前端江太公
2022-03-08 / 0 评论 / 0 点赞 / 884 阅读 / 7,430 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-03-08,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。
广告 广告

常见面试题

1、px、em、rem区别 pt ppi dpi vw vh

px

1像素实际上是一个颜色点,所以又称像素点。大量不同颜色点组成一张图像,因此图像的基本单位是像素px(没有比像素更精细的单位了)。

像素主要用来表示图像大小和显示器分辨率(如1920*1080px)。像素本身的物理尺寸不固定,所以它的物理尺寸没有意义,有意义的是它的数量。

为什么像素的物理尺寸不固定?

像素本身不是物理世界的单位,是一个相对单位,尺寸可大可小。在高密度的屏幕上像素会变小,显示效果更清晰。因为“像素量px = 像素密度ppi x 屏幕尺寸in”,同样是1英寸的屏幕,密度越大,像素越多,则单个像素的物理尺寸越小。

都是图片相关信息,图片体积和像素有什么关系?

通常所说的100KB的图片指的就是图片的体积,首先一张图像在存储时,会描述每个像素点的颜色信息、位置、数量,这些描述数据就是图像的体积,如果像素越多自然图像体积越大。假如一张图片都是一个颜色,图像在保存时就会压缩,只存一个像素点的颜色信息,这样的图像体积会小很多。所以,像素点越多,颜色越复杂,图像体积越大。

为什么我们要买高像素的相机?

日常我们所说的几百万像素的相机,这个几百万像素指的是拍摄最大像素量照片时,图像宽高位置上像素量的乘积。如果像素量大,将来印刷或者在显示器上查看,在1英寸上就有足够多的像素显示,像素密度增加,图像也会更清晰。因此,我们更愿意买高像素的相机。

**总结:**像素px常用来描述图像尺寸和显示器分辨率。

ppi:像素密度(pixel per inch)

1英寸屏幕上显示的像素量,密度单位。决定图片的物理显示尺寸,只有涉及到显示才有意义。值越大,显示越细腻。

**计算公式:**ppi=屏幕对角线上的像素量px/对角线长度inch = √(屏幕横向像素2 + 屏幕纵向像素2)/对角线长度。

img

为什么说ppi决定图片的物理尺寸?

一个手机的显示屏在出厂时就确定了PPI的值,PPI越大,显示越高清。图片的物理尺寸 = PPI * Px,通常一张图像的px确定,ppi越大,则它的物理尺寸越小。所以为什么我们在高PPI的手机上,人眼看到的图像比低PPI的图形小。在设计行业,我们会针对高PPI的手机,设计更大像素的图像也是这个道理。

日常所说的分辨率有两个概念,一个指显示器的分辨率,另一个指图像的分辨率。显示器分辨率指显示器所能显示的像素多少(1920px1080px),显示器可显示的像素越多,画面就越精细,因为屏幕尺寸一定,分辨率越大,像素密度越大。显示器分辨率都用(1920px1080px)这种形式表示,清晰度还需要结合屏幕尺寸计算。图像分辨率则是单位英寸中所包含的像素点数,比如photoshop 里新建画布时设置的图像分辨率72ppi,其定义更趋近于分辨率本身的定义

注意:

同一显示屏上查看图片,像素量越大,图片尺寸越大。

显示分辨率一定的情况下,显示屏越小图像越清晰(比如MacBook),反之,显示屏大小固定时,显示分辨率越高图像越清晰。

对于设计师来说像素密度很重要,需要很据像素密度来切图和适配,理解了像素密度的意义,就理解了几倍图之间的关系。

https://www.jianshu.com/p/4e597cf395df

2、自适应和响应式有何区别

3、一像素问题

4、点透问题

5、上下拉动滚动条时卡顿、慢

6、async await

async

async 函数(包含函数语句、函数表达式、Lambda表达式)会返回一个 Promise 对象,如果在函数中 return 一个直接量,async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象。

Promise.resolve(x) 可以看作是 new Promise(resolve => resolve(x)) 的简写,可以用于快速封装字面量对象或其他对象,将其封装成 Promise 实例。

async function testAsync() {
    return "hello async";
}

testAsync().then(v => {
    console.log(v);    // 输出 hello async
});

它会立即执行,返回一个 Promise 对象,并且,绝不会阻塞后面的语句。这和普通返回 Promise 对象的函数并无二致。

await

await 是在等待一个 async 函数完成。按照语法说明,await 等待的是一个表达式,这个表达式的计算结果是 Promise 对象或者其它值(换句话说,就是没有特殊限定)。

因为 async 函数返回一个 Promise 对象,所以 await 可以用于等待一个 async 函数的返回值——这也可以说是 await 在等 async 函数,但要清楚,它等的实际是一个返回值。注意到 await 不仅仅用于等 Promise 对象,它可以等任意表达式的结果,所以,await 后面实际是可以接普通函数调用或者直接量的。

function getSomething() {
    return "something";
}

async function testAsync() {
    return Promise.resolve("hello async");
}

async function test() {
    const v1 = await getSomething();
    const v2 = await testAsync();
    console.log(v1, v2);
}

test();

Await它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。

阻塞,但是 await 必须用在 async 函数中的原因。async 函数调用不会造成阻塞,它内部所有的阻塞都被封装在一个 Promise 对象中异步执行。

setTimeout 模拟耗时的异步操作,先来看看不用 async/await 会怎么写

function takeLongTime() {
    return new Promise(resolve => {
        setTimeout(() => resolve("long_time_value"), 1000);
    });
}

takeLongTime().then(v => {
    console.log("got", v);
});

改用 async/await

function takeLongTime() {
    return new Promise(resolve => {
        setTimeout(() => resolve("long_time_value"), 1000);
    });
}

async function test() {
    const v = await takeLongTime();
    console.log(v);
}

test();

async/await 的优势在于处理 then 链

业务,分多个步骤完成,每个步骤都是异步的,而且依赖于上一个步骤的结果。用 setTimeout 来模拟异步操作:

/**
 * 传入参数 n,表示这个函数执行的时间(毫秒)
 * 执行的结果是 n + 200,这个值将用于下一步骤
 */
function takeLongTime(n) {
    return new Promise(resolve => {
        setTimeout(() => resolve(n + 200), n);
    });
}

function step1(n) {
    console.log(`step1 with ${n}`);
    return takeLongTime(n);
}

function step2(n) {
    console.log(`step2 with ${n}`);
    return takeLongTime(n);
}

function step3(n) {
    console.log(`step3 with ${n}`);
    return takeLongTime(n);
}

现在用 Promise 方式来实现这三个步骤的处理

function doIt() {
    console.time("doIt");
    const time1 = 300;
    step1(time1)
        .then(time2 => step2(time2))
        .then(time3 => step3(time3))
        .then(result => {
            console.log(`result is ${result}`);
            console.timeEnd("doIt");
        });
}

doIt();

// c:\var\test>node --harmony_async_await .
// step1 with 300
// step2 with 500
// step3 with 700
// result is 900
// doIt: 1507.251ms

输出结果 resultstep3() 的参数 700 + 200 = 900doIt() 顺序执行了三个步骤,一共用了 300 + 500 + 700 = 1500 毫秒,和 console.time()/console.timeEnd() 计算的结果一致。

如果用 async/await 来实现呢,会是这样

async function doIt() {
    console.time("doIt");
    const time1 = 300;
    const time2 = await step1(time1);
    const time3 = await step2(time2);
    const result = await step3(time3);
    console.log(`result is ${result}`);
    console.timeEnd("doIt");
}

doIt();

业务要求复杂点,是三个步骤,但每一个步骤都需要之前每个步骤的结果

function step1(n) {
    console.log(`step1 with ${n}`);
    return takeLongTime(n);
}

function step2(m, n) {
    console.log(`step2 with ${m} and ${n}`);
    return takeLongTime(m + n);
}

function step3(k, m, n) {
    console.log(`step3 with ${k}, ${m} and ${n}`);
    return takeLongTime(k + m + n);
}

这回先用 async/await 来写:

async function doIt() {
    console.time("doIt");
    const time1 = 300;
    const time2 = await step1(time1);
    const time3 = await step2(time1, time2);
    const result = await step3(time1, time2, time3);
    console.log(`result is ${result}`);
    console.timeEnd("doIt");
}

doIt();

// c:\var\test>node --harmony_async_await .
// step1 with 300
// step2 with 800 = 300 + 500
// step3 with 1800 = 300 + 500 + 1000
// result is 2000
// doIt: 2907.387ms

利用try-catch处理promise的reject状态

function timeout(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

async function asyncPrint(value, ms) {
  await timeout(ms);
  console.log(value)
}

asyncPrint('hello world', 50);


async function myFunction() {
  try {
    await somethingThatReturnsAPromise();
  } catch (err) {
    console.log(err);
  }
}

// 另一种写法

async function myFunction() {
  await somethingThatReturnsAPromise().catch(function (err){
    console.log(err);
  });
}

7、generator

8、跨域解决方案

9、Object.defineProperty

Object.efineProperty 需要三个参数(object , propName , descriptor

object 对象 ,目标对象

propName 属性名 , 添加的属性的名 ,类型:String

**descriptor **属性描述 属性的特性,类型:Object

示例:

var user = {};
Object.defineProperty(user,"name",{
 value:"王凯"
})
console.log(user);//{name: "王凯"}

同样,可以设置各种类型的属性

var` `user = {};
Object.defineProperty(user,"name",{
 ``value:``"狂奔的蜗牛"
})
Object.defineProperty(user,"isSlow",{
 ``value:``true
})
Object.defineProperty(user,"sayHi",{
 ``value:``function` `() { console.log("Hi !") }
})
Object.defineProperty(user,"age",{
 ``value:12
})
Object.defineProperty(user,"birth",{
  value:{
    date:"2018-06-29",
    hour:"15:30"
  }
})
console.log(user);

设置可写权限

var` `user = {};
Object.defineProperty(user,``"name"``,{
 ``value:``"狂奔的蜗牛"``,
 ``writable:``true
})
console.log(user);
user.name=``"新=>狂奔的蜗牛"
console.log(user);

设置可枚举权限

var` `user ={
 ``name:``"狂奔的蜗牛"``,
 ``age:25
} ;
//定义一个性别 可以被枚举
Object.defineProperty(user,``"gender"``,{
 ``value:``"男"``,
 ``enumerable:``true
})
//定义一个出生日期 不可以被枚举
Object.defineProperty(user,``"birth"``,{
 ``value:``"1956-05-03"``,
 ``enumerable:``false
})

//es6
var` `keys=Object.keys(user)
console.log(keys);
// ["name", "age", "gender"]
console.log(user);

// {name: "狂奔的蜗牛", age: 25, gender: "男", birth: "1956-05-03"}
console.log(user.birth);
// 1956-05-03 

设置可删除权限

var` `user ={
 ``name:``"狂奔的蜗牛"``,
 ``age:25
} ;
//定义一个性别 可以被删除和重新定义特性
Object.defineProperty(user,``"gender"``,{
 ``value:``"男"``,
 ``enumerable:``true``,
 ``configurable:``true
})
//删除前
console.log(user);
// {name: "狂奔的蜗牛", age: 25, gender: "男"}
//删除一下
delete` `user.gender;
console.log(user);
// {name: "狂奔的蜗牛", age: 25}
//重新定义特性
Object.defineProperty(user,``"gender"``,{
 ``value:``"男"``,
 ``enumerable:``true``,
 ``configurable:``false
})
//删除前
console.log(user);
// {name: "狂奔的蜗牛", age: 25, gender: "男"}
//删除一下 删除失败
delete` `user.gender;
console.log(user);
// {name: "狂奔的蜗牛", age: 25, gender: "男"}

Object.defineProperty方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象

  • value: 设置属性的值

  • writable: 值是否可以重写。true | false

  • enumerable: 目标属性是否可以被枚举。true | false

  • configurable: 目标属性是否可以被删除或是否可以再次修改特性 true | false

  • set: 目标属性设置值的方法

  • get:目标属性获取值的方法  

10、Vue 2.0 和3.0区别

11、BFC

12、ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例

0
广告 广告

评论区