日升昌面试题

基础篇

1、什么是盒子模型?

页面就是由一个个盒模型堆砌起来的,每个HTML元素都可以叫做盒模型,盒模型由外而内包括:边距(margin)、边框(border)、填充(padding)、内容(content)。它在页面中所占的实际宽度是margin + border + paddint + content 的宽度相加。

2、行内元素、块级元素有哪些,有何区别,如何转换?

分别有:块级元素div p h1 h2 h3 h4 form ul 行内元素: a b br i span input select

区别

行内元素会在一条直线上排列,都是同一行的。块级元素各占据一行,垂直方向排列。

块级元素可包含行内、块级元素。行内元素不能包含块级元素,只能包含文本或其它行内元素。

行内元素与块级元素属性的不同,主要是盒模型属性上:行内元素设置width无效,height无效(可以设置line-height),margin上下无效,padding上下无效

转换:display:block;设为块级元素。display:inline;设为行内元素

3、前端页面有哪三层构成,分别是什么?作用是什么?

结构层 Html 、表示层 CSS、 行为层 js

4、如下有一段html,请用原生js或jq满足如下要求【dom】

<div class="mydiv">
    <lable>用户名:</lable>
    <input type="text" data-name="uname" value="hello"/>
</div>

a:将lable中的内容设置为 当前值+当前时间戳

b:将input的值 设置为 当前值+当前时间戳

c:将input中的自定义属性data-name设置为 当前值+当前时间戳

高级篇

5、描述一下js都有哪些作用域。如下代码的结果是什么,并且分析原因【作用域】

var arr = [];
for(var i=0;i<10;i++){
    arr[i]=function(){
        return i;
    }
}
var res=arr[3]()
console.log(res);

显然这段代码输出10,并没有向我们期望的返回3,原因也很简单(js的变量提升)函数在调用时候访问的是一个全局作用域的i,此时for循环已经执行完毕,全局变量i=10;

如果想输出3,两种办法,1中是用es6的let。另一种是利用函作用域通过立即执行函数来对其闭包。具体代码如下

 

6、js有几种数据类型,分别都有哪些。按照内存结构如何区分,存储结构有何区别

5种简单数据类型:Undefined, Null, Boolean, Number, String.

1种复杂数据类型:Object(Array,Date,Function).

上面的5种简单数据类型又称为基本数据类型,复杂数据类型又称为引用数据类型。基本数据类型保存在栈内存,引用数据类型实际上是一个指针,这个指针也保存在栈中,但是这个指针指向的对象则保存在堆内存中。

var arr = [];
 for(var i=0;i<10;i++){
     arr[i]=(function(i){
         return function(){
             return i;
         }
     })(i)
 }
 var res=arr[3]()
 console.log(res);
 // 这样一来数组的每个函数就处于一个立即执行函数的函数作用域中,该立即执行函数传入i,其实for循环执行了如下代码:
 // array[0]=(function(i){
 //     return function(){
 //         return i;
 //     }
 // })(0);
 // array[1]=(function(i){
 //     return function(){
 //         return i;
 //     }
 // })(1);
 // 这样一来,数字组中每个函数对应一个单独的函数作用域(立即执行函数的)这里共创建了10个函数作用域,这些函数作用域里的i值就是执行时候传入的0……9,当执行
 // array[3]();时候函数访问的i值是其对应的立即执行函数作用域里的 i,而不是全局的i值,这样我们就得到了预期的效果。
// 说得到这里我们简单来说一下闭包,闭包可以理解为一个闭包就是一个没有释放资源的栈区,栈区内的变量处于激活状态。上面的例子中for循环在执行时系统分配内存,js执行线程创建执行栈区,执行

7、目前为止,js都有哪些实现继承的办法。【面向对象】

原型链继承:将父类的实例作为子类的原型

借用构造函数继承:apply与call

es6:关键字extend

8、如何避免回调地狱(如何优雅的处理回调),并给出如下代码优雅解决方案【es6+】

service.js代码如下

let myService={
    /**
    *功能:获取教师id,即tid
    *参数:tno--教师编号
    */
    getTcId:function (param) {
        let result=$.post('http://localhost:8080/getTcId',param);
        return result;
    },


    /**
    *功能:获取老师详细信息
    *参数:tid--教师id
    */
    getTcInfo:function (param) {
        let result=$.post('http://localhost:8080/getTcInfo',param);
        return result;
    }
}
 

index.html如下

<button>获取张老师信息</button>
<div class="tinfo"></div>
<script src="service.js"></script>
<script>
   $('button').click(function () {
       let param={tno:20160808};
       getTcId(param).then(function (rep) {
           let tid=rep.tid;
           let param={tid:tid}
           getTcInfo(param).then(function (rep) {
                $('tinfo').html(`老师的详细信息为:${rep}`)
           })
       })
   })
</script>

更改index.html中的script部分,使其代码优雅处理回调

参考答案:

$('button').click(async function () {
    let tid=(await getStudent({tno:20160808})).tid;
    let tinfo=await getStudent({tid:tid})
    $('tinfo').html(`老师的详细信息为:${rep}`)
})

组件篇

9、什么是mvvm,它和mvc有何区别?【设计思想】

什么是mvvm

MVVM是Model-View-ViewModel的缩写,是一种设计思想。Model 层代表数据模型;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model对象。

在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。

ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

和传统mvc的区别

mvc和mvvm其实区别并不大。都是一种设计思想。主要就是mvc中Controller演变成mvvm中的viewModel。mvvm主要解决了mvc中大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。

10、Vue组件之间如何通信,父子组件通信(父-->子,子-->父),兄弟组件通信

父组件通过标签上面定义传值,子组件通过props方法接受数据【vue通信】

//父组件中
<child message="hello!"></child>


//子组件中
<template>
  <div>
     {{message}}
  </div>
</template>
export default {
   name: "baseLayer",
   props:['message']
}


/*需要注意的是,子组件不能修改父组件的props
因为一个父组件下可能有多个子组件,如果某个子组件修改了父组件传递的props,
很可能导致其他子组件也就跟着变化,最终导致整个应用的状态难以管理和维护
所以不允许子组件修改props*/

子->父: 子组件自定义事件,子组件通过$emit方法传递参数,父组件可以在使用子组件的地方用 v-on 来监听子组件触发的事件

//父组件中
<template>
  <div class="father">
    <child v-on:result="clickChild"></child>
  </div>
</template>
<script>
  import child from '@/compoment/child'
  export default {
    name:'father',
    components:{child},
    methods:{
        clickChild(type){
            alert(type)
        }
    }
  }
</script>




//子组件中
<template>
  <div>
     <button v-on:click="clickBtn(true)">确定</button>
  </div>
</template>
export default {
   name: "child",
   methods:{
        clickBtn(b){
            //监听result变化, 并发出通知
            //(在angularjs中叫做广播,angularjs提供了emit,
            //broadcast和$on服务用于向父中传递消息)
            this.$emit('result', b);
        }
    }

兄弟或者复杂组件间的通信,推荐使用vuex,参考笔记

http://www.cnblogs.com/flyings/p/9022583.html

10、vue-router如何定义一个带参数的路由,并且写出跳转至此路由,此路由对应的组件如何接受对应的参数【vue路由】

export default new Router({
  routes: [
    {
      path: '/',
      name: 'home',
      component: home
    },
    {
     path: '/blogDetail/:bid',
     name: 'BlogDetail',
     component: blogDetailCmp
    }]

//跳转至此组件,并携带参数

编程式:this.$router.push({ name: 'BlogDetail', params: { bid: 20160808}})

声明式:<router-link :to="{ name: 'user', params: { bid: 20160808 }}">详情</router-link>

//此组件如何接受参数

this.$route.params.bid

11、vue生命周期函数(钩子)都有哪些?DOM 渲染在 哪个周期中就已经完成。请列举出3个Vue中常用的生命周期钩子函数

【vue钩子】

可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后

在mounted阶段

created: 实例已经创建完成之后调用,在这一步,实例已经完成数据观测, 属性和方法的运算, watch/event事件回调. 然而, 挂载阶段还没有开始, $el属性目前还不可见

mounted: el被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。

activated: keep-alive组件激活时调用

12、v-show和v-if指令的共同点和不同点 【vue指令】

v-show指令是通过修改元素的display的CSS属性让其显示或者隐藏

v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果

13、如何让css只在当前组件中起作用【vue组件】

将当前组件的<style>修改为<style scoped>

14、如何定义一个vue组件,别人只需要安装你的插件,无需再页面引入import 模板也无需插入该组件,便可以直接调用。比如toast弹窗插件。某个组件用的时候,直接 this.$toast('验证中通过',1000) ,既可以弹出。【vue组件进阶】

./plugin/modal/index.js

import mytoast from './toast';
export  default {
  install:function(Vue){
    //生成一个Vue的子类,同时这个子类也就是组件.并生成一个该子类的实例
    const Toast = Vue.extend(mytoast);
    let toast = new Toast();




    // 将这个实例挂载在我创建的div上, 并将此div加入全局挂载点内部
    toast.$mount(document.createElement('div'))
    document.body.appendChild(toast.$el)


    //挂在到全局
    Vue.prototype.$toast=function (msg,time) {
      toast.msg=msg;
      toast.open();
      if(time){
        setTimeout(function () {
          toast.close();
        },time)
      }
    }

main.js启动直接注入到全局实例中就行

import modal from './plugin/modal/index'
Vue.use(modal)//启用自己的插件

15、<keep-alive></keep-alive>的作用是什么,如果使用了keep-alive,页面中哪些钩子会被触发【vue原生内置组件】

<keep-alive></keep-alive> 包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。比如滚动的位置,表单的值

当组件在 <keep-alive> 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。

16、vue中如何定义一个全局的插件,在任何组件中都可以使用。比如定义个工具类,工具类里有获取当前时间的插件。 我想在任意组件中都可以 this.utils.getTime()来调用。请大致写出【vue插件】

17、vue常用的指令都有哪些【vue指令】

v-if:判断是否隐藏;v-for:数据循环;v-bind:绑定一个属性; v-model:实现双向绑定 ; v-on事件; v-html渲染dom; v-once只绑定一次就不在改变...

18、vue如何自定指令

分为全局和局部

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})
 

directives: {
  focus: {
    // 指令的定义
    inserted: function (el) {
      el.focus()
    }
  }
}


使用

<input v-focus>

 

 

19、VNode是什么?虚拟 DOM是什么?

Vue在 页面上渲染的节点,及其子节点称为“虚拟节点 (Virtual Node)”,简写为“VNode”。“虚拟 DOM”是由 Vue 组件树建立起来的整个 VNode 树的称呼。

 

20、谈谈你对单页Web应用(single page web application,SPA)的理解

原文地址:https://www.cnblogs.com/dshvv/p/11335009.html