面试总结

 

一、选择除第一个元素外的所有元素

<div class="father">
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
    </div>
.father .child:not(:first-child) {
 
}

二、flex:1的原理

flex 是 flex-growflex-shrinkflex-basis的缩写

flex-grow 属性用于设置或检索弹性盒子的扩展比率

flex-basis 属性用于设置或检索弹性盒伸缩基准值

flex-shrink的默认值为1,如果没有显示定义该属性,将会自动按照默认值1在所有因子相加之后计算比率来进行空间收缩。

<div class="parent">
    <div class="item-1"></div> 
    <div class="item-2"></div> 
    <div class="item-3"></div> 
</div> 
<style type="text/css"> 
    .parent { display: flex; width: 600px; } 
    .parent > div { height: 100px; } 
    .item-1 { width: 140px; flex: 2 1 0%; background: blue; } 
    .item-2 { width: 100px; flex: 2 1 auto; background: darkblue; } 
    .item-3 { flex: 1 1 200px; background: lightblue; } 
</style> 
  • 主轴上父容器总尺寸为 600px

  • 子元素的总基准值是:0% + auto + 200px = 300px,其中

0% 即 0 宽度

auto 对应取主尺寸即 100px

  • 故剩余空间为 600px - 300px = 300px

  • 伸缩放大系数之和为: 2 + 2 + 1 = 5

  • 剩余空间分配如下:

item-1 和 item-2 各分配 2/5,各得 120px

item-3 分配 1/5,得 60px

  • 各项目最终宽度为:

- item-1 = 0% + 120px = 120px

- item-2 = auto + 120px = 220px

- item-3 = 200px + 60px = 260px

  • 当 item-1 基准值取 0% 的时候,是把该项目视为零尺寸的,故即便声明其尺寸为 140px,也并没有什么用,形同虚设

  • 而 item-2 基准值取 auto 的时候,根据规则基准值使用值是主尺寸值即 100px,故这 100px 不会纳入剩余空间

三、vue中,vue.set、vue.use和.sync修饰符的作用

vue.set:给对象新增属性

解决“当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,不会更新视图”的问题

vue.use: 使用插件(前提:插件有暴露install方法)

// 调用 `MyPlugin.install(Vue)`
Vue.use(MyPlugin)

new Vue({
  // ...组件选项
})

.sync:对一个 prop 进行“双向绑定”。

父组件:

<text-document v-bind:title.sync="doc.title"></text-document>

子组件:

this.$emit('update:title', newTitle)

四、写出执行结果

var a = 3

function fn(a) {
  console.log(a) // ƒ a() {)
  var a = 2
  function a() {

   }
  console.log(a) // 2
}
fn(1)

五、微信小程序的理解

1.运行环境

       根据微信官方的说明,wa的运行环境有3个平台,IOS的webkit(苹果开源的浏览器内核),Android的X5(QQ浏览器内核),开发时用的nw.js(C++实现的web转桌面应用);

2.本质

       本质就是富单页面web应用。首先,一个微信小程序应用程序就是一个单页面应用,所有的页面渲染和事件处理,都在一个页面内进行,但与传统的webapp不同的是,它也可以做得很丰富,就像native app一样,可以调用原生的各种接口,像网络状态、罗盘,重力,拨打电话

3.页面的脚本逻辑是在JsCore中运行,JsCore是一个没有窗口对象的环境

六、多维数组转一维数组

        let arr = [1, 2, {
            a: 2
        }, true, 3, 4, 5, [6, 7, 8, [9, 10, 11, 12, [13, 14, 15, 16]]]]

        let newArr = [] // 存放转化后的一维数组

        function arrConversion(arr) {
            for (let i = 0; i < arr.length; i++) {
                if (Array.isArray(arr[i])) {
                    arrConversion(arr[i])
                } else {
                    newArr.push(arr[i])
                }
            }
        }
        arrConversion(arr)
        console.log(newArr)
//(18) [1, 2, {…}, true, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

七、使用Array.isArray和instanceof数组之间的区别

isArray是一个ES5方法,所以不支持旧的浏览器,但它可靠地确定一个对象是否是一个数组。当不存在 Array.isArray() ,可以用 Object.prototype.toString.call() 实现

instanceof只检查Array.prototype是否在对象的[[Prototype]]链上。它在跨框架检查数组时失败,因为用于实例的Array构造函数可能与用于测试的数组不同。

八、写出执行结果

console.log(111)
    p()
      .then(result => {
        console.log(`p result:${result}`)
      })
      .catch(err => {
        console.log(`p err :${err}`)
      })
    p1()
      .then(result => {
        console.log(`p1 result:${result}`)
      })
      .catch(err => {
        console.log(`p1 err :${err}`)
      })
    p2()
      .then(result => {
        console.log(`p2 result:${result}`)
      })
      .catch(err => {
        console.log(`p2 err :${err.message}`)
      })
    function p() {
      return new Promise((resolve, reject) => {
        console.log(222)
        setTimeout(() => {
          console.log('async in p')
          reject('err in p')
          console.log('content after p reject')
        }, 200)
      })
    }
    function p1() {
      return new Promise((resolve, reject) => {
        console.log(333)
        setTimeout(() => {
          console.log('async in p1')
          resolve('resolev in p1')
          console.log('content after p1 resolve')
        }, 250)
      })
    }
    function p2() {
      return new Promise((resoleve, reject) => {
        console.log(444)
        setTimeout(() => {
          console.log('async in p2')
          return reject(new Error('p2error'))
          console.log('content after p2 return')
        }, 300)
      })
    }

九、BFC和FFC

1.BFC

BFC(Block Formatting Contexts)直译为"块级格式化上下文"。

Block Formatting Contexts就是页面上的一个隔离的渲染区域,容器里面的子元素不会在布局上影响到外面的元素,反之也是如此。

如何产生BFC?

  • float的值不为none。

  • overflow的值不为visible。

  • position的值不为relative和static。

  • display的值为table-cell, table-caption, inline-block中的任何一个。

那BFC一般有什么用呢?

比如常见的多栏布局,结合块级别元素浮动,里面的元素则是在一个相对隔离的环境里运行。

bfc 解决什么样的问题?

bfc区域不与float 区域重叠。
双边距问题。
计算bfc高度,浮动元素也参与计算。
子集浮动元素,父级overflow:hidden 具有高度

2.FFC

FFC(Flex formatting contexts):自适应格式上下文。

display值为flex或者inline-flex的元素将会生成自适应容器(flex container),可惜这个牛逼的属性只有谷歌和火狐支持,不过在移动端也足够了,至少safari和chrome还是OK的,毕竟这俩在移动端才是王道。

Flex Box由伸缩容器和伸缩项目组成。通过设置元素的 display属性为 flex 或 inline-flex 可以得到一个伸缩容器。设置为 flex 的容器被渲染为一个块级元素,而设置为 inline-flex 的容器则渲染为一个行内元素。伸缩容器中的每一个子元素都是一个伸缩项目。伸缩项目可以是任意数量的。伸缩容器外和伸缩项目内的一切元素都不受影响。简单地说,Flexbox 定义了伸缩容器内伸缩项目该如何布局。

十、eventLoop

Event Loop

JavaScript中,任务被分为两种,一种宏任务(MacroTask)也叫Task,一种叫微任务(MicroTask)。

MacroTask(宏任务)

  • script全部代码、setTimeoutsetIntervalsetImmediate(浏览器暂时不支持,只有IE10支持,具体可见MDN)、I/OUI Rendering

MicroTask(微任务)

  • Process.nextTick(Node独有)PromiseObject.observe(废弃)MutationObserver(具体使用方式查看这里

浏览器中的Event Loop

Javascript 有一个 main thread 主线程和 call-stack 调用栈(执行栈),所有的任务都会被放到调用栈等待主线程执行。

JS调用栈

JS调用栈采用的是后进先出的规则,当函数执行的时候,会被添加到栈的顶部,当执行栈执行完成后,就会从栈顶移出,直到栈内被清空。

同步任务和异步任务

Javascript单线程任务被分为同步任务异步任务,同步任务会在调用栈中按照顺序等待主线程依次执行,异步任务会在异步任务有了结果后,将注册的回调函数放入任务队列中等待主线程空闲的时候(调用栈被清空),被读取到栈内等待主线程的执行。

事件循环的进程模型

  • 选择当前要执行的任务队列,选择任务队列中最先进入的任务,如果任务队列为空即null,则执行跳转到微任务(MicroTask)的执行步骤。
  • 将事件循环中的任务设置为已选择任务。
  • 执行任务。
  • 将事件循环中当前运行任务设置为null。
  • 将已经运行完成的任务从任务队列中删除。
  • microtasks步骤:进入microtask检查点。
  • 更新界面渲染。
  • 返回第一步。

执行进入microtask检查点时,用户代理会执行以下步骤:

  • 设置microtask检查点标志为true。
  • 当事件循环microtask执行不为空时:选择一个最先进入的microtask队列的microtask,将事件循环的microtask设置为已选择的microtask,运行microtask,将已经执行完成的microtasknull,移出microtask中的microtask
  • 清理IndexDB事务
  • 设置进入microtask检查点的标志为false

十一、webpack中loader和plugin的概念理解

对于loader,它就是一个转换器,将A文件进行编译形成B文件,这里操作的是文件,比如将A.scss或A.less转变为B.css,单纯的文件转换过程;

对于plugin,它就是一个扩展器,它丰富了wepack本身,针对是loader结束后,webpack打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听webpack打包过程中的某些节点,例如

run:开始编译
make:从entry开始递归分析依赖并对依赖进行build
build-moodule:使用loader加载文件并build模块
normal-module-loader:对loader加载的文件用acorn编译,生成抽象语法树AST
program:开始对AST进行遍历,当遇到require时触发call require事件
seal:所有依赖build完成,开始对chunk进行优化(抽取公共模块、加hash等)
optimize-chunk-assets:压缩代码
emit:把各个chunk输出到结果文件


通过对节点的监听,从而找到合适的节点对文件做适当的处理。

十二、不用input,实现vmodel

使用v-model的时候,vue会绑定组件的value属性,在自定义组件上使用v-model,然后浏览器审查元素,就会发现组件上做了一个vue属性。

如果在组件做出修改的话,就可以直接发射一个input的事件,把对应的值弹出到外面,就实现了双向绑定

// 父组件
<template>
  <div id="app">
    <HelloWorld v-model="msg" />
    <h1 style="color:green">{{msg}}</h1>
    <button @click="test()">ok</button>
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";

export default {
  name: "app",
  components: {
    HelloWorld
  },
  data() {
    return {
      msg: 2
    };
  },
  methods: {
    test() {
      this.msg -= 1;
    }
  }
};
</script>

 

// 子组件
<template>
  <div class="hello">
    <h1 v-bind:title="value" @click="close()">{{ value }}</h1>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    value: Number
  },
  data() {
    return {
    };
  },
  methods: {
    close() {
      this.num+=1;
      this.$emit("input", this.value+1);
    }
  }
};
</script>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Neo 丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值