欢迎光临散文网 会员登陆 & 注册

面试题整理(华为)

2019-07-17 18:43 作者:Alice铛铛铛  | 我要投稿

题目概览:

  1. vuex的功能?能否进行兄弟组件之间的传值?

  2. Axios调取数据?

  3. 继承prototype大概是怎么实现的?

  4. es6中和原型一样用来继承的class和继承是怎么实现的?

  5. jQuery和Vue使用起来有什么区别?

  6. vue父子组件传值怎么实现的?

  7. 兄弟组件传值怎么实现的?

  8. 怎么调程序中出现的代码?

  9. js的垃圾回收机制?

  10. es6中const、let、var之间的区别?

  11. 闭包是什么?用let怎么实现闭包?

详解:

1. vuex的功能?能否进行兄弟组件之间的传值?

vuex专为 Vue.js 应用程序开发的状态管理模式。主要用于管理vue中的数据,可以兄弟组件互相传值;

state:管理项目的数据(进行数据初始化);

mutations:主要用于操作state中的数据store.commit('increment')

action:通过提交 mutation 的方式,而非直接改变 store.state.count,是因为我们想要更明确地追踪到状态的变化;

getter:就像计算属性,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算;getter 接受 state 作为其第一个参数;

<div id="app1">
   {{count}}
</div>//store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
   state:{
       count:0
   }
});

new Vue({
   el:'#app1',
   store,
   computed:{
       count(){
           return this.$store.state.count
       }
   }
})

2. Axios调取数据?

axios的特性

1、可以从浏览器中创建XHR对象

2、可以从nodeJS中创建HTTP请求

 3、支持Promise 

4、可以拦截请求和响应 

5、可以转换请求数据和响应数据 

6、可以取消请求 

7、可以自动转换JSON数据 

8、客户端支持防御XSRF

axios get 方法:仅仅请求后台数据

axios.get('index.php')
         .then(function (response) {
               console.log(response);
         })

         .catch(function (error) {
               console.log(error);
         });

aixos post方法post请求更多的是要提交数据,params属性里的数据会出现在请求主体中。

axios.post('/user', {
       firstName: 'Fred',
       lastName: 'Flintstone'
 })
 .then(function (response) {
       console.log(response);
 })
 .catch(function (error) {
       console.log(error);
 });

多并发请求,一次性发几个请求

function getUserAccount() {
     return axios.get('/user/12345');
}

function getUserPermissions() {
     return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
     .then(axios.spread(function (acct, perms) {
   // acct为第一个请求的结果,perms为第二个请求的结果
 }));

设置拦截器

//请求拦截器
 axios.interceptors.request.use(  
       config => {
           btn.innerHTML='请求数据中';
           return config;
       },

       // 错误时发生的事情
       err => {
           console.log(err)
       });
 

// 响应应拦截器

       axios.interceptors.response.use(
       config => {
           btn.innerHTML='请求数据成功';
           return config;
       },

       // 错误时发生的事情
       err => {
           console.log(err)
       });

设置自定义请求头

第一步:先安装Axios:npm install axios --save

第二步:再在main.js中引入Axios:

    import axios from 'axios'
    Vue.prototype.$http = axios;

第三步:即可在组件中调用Axios:

this.$axios.get('index.php/url')
     .then(response => {
       console.log(response)
     })

    .catch(error => {
       console.log(error)
     });

第四步:然后设置自定义的头请求:

axios.defaults.timeout = 5000;//请求超时的时间设定

axios.defaults.headers.post['Content-Type'] = 'application/json'; //axios默认的请求方式

axios.defaults.baseURL = 'http://localhost:8008';//axios默认的请求地址

axios.defaults.headers.common["token"] = "noname";//有些接口必须登录才可以调用,而登陆注册并未写好,后台给了一个故固定的token,写在了头里面

3. 继承prototype大概是怎么实现的?

实例对象per的构造器constructor是指构造函数Person;

console.log(per.constructor==Person);//true

实例对象的_proto_和构造函数中的prototype相等;

console.log(per._proto_.constructor==Person.prototype.constructor);//true


原型链:实例对象使用的属性或者方法,先在实例中查找,找到了则直接使用,找不到则去实例对象的__proto__指向的原型对象prototype中找,找到了则使用,找不到则报错。


实例对象中有_proto_这个属性,叫原型,也是一个对象,这个属性是给浏览器使用,

不是标准的属性----->proto----->可以叫原型对象;

构造函数中有prototype这个属性,叫原型,也是一个对象,这个属性是给程序员使用,

是标准的属性------>prototype--->可以叫原型对象;

1.原型继承核心就是让自定义的构造器的prototype对象指向父类构造器生成的对象

//Person是个构造函数,Per是自定义的构造器
function Per(){}
Per.prototype = new Person('Alice');
const person = new Per()
//继承父类实例定义的所有属性以及父类构造器原型上的属性

2. 借用函数继承:通过函数对象本身的 call 和 apply 来显示的指定函数调用时必备的参数;

function Per(name){
   Person.call(this,name)//当成了普通函数来使用
}

const person = new Per('Alice')
//只能调用Person中定义的属性和函数,无法调用Person定义在prototype上的属性和方法

3.组合继承(原型链+借用函数):[为了解决借用函数无法使用函数原型上的属性和方法]

function Per(name){
   Person.call(this,name)
//当成了普通函数来使用
}
Per.prototype = new Person('Alice')//这样写,会造成Animal实例化两次,没有自己的原型
//或者
Per.prototype = Person.prototype//这样写,就不会造成多次实例化
const person = new Per('Alice')

4.原型式继承:提供一个被继承的对象,把这个对象挂在到某个构造函数的prototype上,再利用new;

function inherit (object) {
     function fn () {}   // 提供一个函数
     fn.prototype = object ; // 设置函数的prototype
     return new fn()    // 返回这个函数实例化出来的对象
}
const person = Person('Alice');
const me=inherit(person);//可以继承peroson对象上所有的方法和属性

5.寄生式继承

6.寄生组合式继承:利用 Object.create() 方法

4. es6中和原型一样用来继承的class和继承是怎么实现的?

typeof Point // "function",类的数据类型就是函数
Point === Point.prototype.constructor // true,类本身就指向构造函数

使用的时候,也是直接对类使用new命令,跟构造函数的用法完全一致,不使用new会报错。

类的所有方法都定义在类的prototype属性上面。

class Point {
     constructor() {
           // ...
     }
     toString() {
           // ...
     }
     toValue() {
           // ...
     }
}

// 等同于
Point.prototype = {
     constructor() {},
     toString() {},
     toValue() {},
};

//Object.assign方法可以很方便地一次向类添加多个方法
Object.assign(Point.prototype, {
     toString(){},
     toValue(){}
});

类不存在变量提升(hoist),这一点与 ES5 完全不同。

Class 可以通过extends关键字实现继承。

class ColorPoint extends Point {} //ColorPoint继承了Point类所有的属性和方法

super关键字,表示父类的构造函数,用来新建父类的this对象。

子类必须在constructor方法中调用super方法,否则新建实例时会报错,只有调用super之后,才可以使用this关键字。

区别

ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面Parent.apply(this))。

ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this


Class 作为构造函数的语法糖,同时prototype属性和__proto__属性,因此同时存在两条继承链。

(1)子类的_proto_属性,表示构造函数的继承,总是指向父类。

(2)子类prototype属性的_proto_属性,表示方法的继承,总是指向父类的prototype属性。

子类实例的__proto__属性的__proto__属性,指向父类实例的__proto__属性。也就是说,子类的原型的原型,是父类的原型。

Object.getPrototypeOf方法判断,一个类是否继承了另一个类。

5. jQuery和Vue使用起来有什么区别?

       从jquery到vue或者说是到mvvm的转变则是一个思想的转变,是将原有的直接操作dom的思想转变到操作数据上去。

       从技术角度讲,Vue.js 专注于 MVVM 模型的 ViewModel 层。它通过双向数据绑定把 View 层和 Model 层连接了起来,通过对数据的操作就可以完成对页面视图的渲染。


       jQuery是使用选择器($)选取DOM对象,对其进行赋值、取值、事件绑定等操作,和原生的区别只在于可以更方便的选取和操作DOM对象,其数据和界面是在一起的。

       Vue则是通过Vue对象将数据和View层分离开来。对数据进行操作不再需要引用相应的DOM对象,通过Vue对象这个vm实现相互的绑定。


       vue适用的场景:复杂数据操作的后台页面,表单填写页面;vue侧重数据绑定;

  jquery适用的场景:比如说一些html5的动画页面,一些需要js来操作页面样式的页面;jquery侧重样式操作,动画效果等;

6. vue父子组件传值怎么实现的?

  1. 父传子:

    先在父组件中绑定变量<child :msg="parent"></child>,parent是定义在父组件中的变量/值;

    再在子组件中添加props属性接收父组件传递过来的变量props:['msg']

    最后就可以在子组件中使用{{msg}}来表示父组件中parent变量中的值了。

  2. 子传父:

    先在子组件中绑定事件@change="sendChild",触发的时候在setChild事件中$emit()触发父组件中的函数,并将子组件中的变量作为参数传递;

    methods:{
       sendChild:function(){
           this.$emit('transparent',this.msg)
       }
    }

    父组件中绑定事件<child @transparent="getChild"></child>,当子组件触发这个事件的时候,就可以调用getChild方法获取到传递过来的参数

    methods:{
       getChild(msg){
           this.user=msg;
       }
    }

7. 兄弟组件传值怎么实现的?

1. 兄弟组件互相传值,通过Vuex状态管理传值

先通过npm加载vuex,创建store.js文件

//store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const state={name:'Alice'};
const mutations={
       newName(state,message){
           state.name=message
       }
}
export default new Vuex.Store({state,mutations})

2. 兄弟组件互相传值,引入bus.js文件,发布者订阅者模式:

import Bus from './bus.js'   //一个子组件触发
  methods:{
      Bus.$emit('触发的方法名',需要传递的值);
  }   //一个子组件监听
  mounted:{
      bus.$on("方法名",(传递的值)=>{ })
  }

3. 兄弟组件互相传值$root

//一个子组件触发
this.$root.$emit('触发的方法名',需要传递的值);
this.$root.$off("方法名");//每次进入先关闭一下

//一个子组件监听

this.$root.$on("方法名",(传递的值)=>{ })

8. 怎么调程序中出现的代码?

alert('方法一')
console.log('方法二') 

Chrome中的开发者工具:断点设置、调试功能

9. js的垃圾回收机制?(摘自红宝书)

  1. 离开作用域的值将被自动标记为可以回收,因此将在垃圾收集期间被删除;

  2. “ 标记清除 ” 是目前最主流的垃圾收集算法,这种算法的思想是给当前不使用的值加上标记,然后再回收其内存(当变量进入环境时,将变量标记为“进入环境”。当变量离开环境时,将其标记为“离开环境”,标记“离开环境”的就回收内存);

  3. 另一种垃圾收集算法是 “ 引用计数 ” ,这种算法的思想是跟踪记录所有值被引用的次数。JavaScript引擎目前都不再使用这种算法;但在 IE 中访问非原生JavaScript对象(如DOM元素)时,这种算法仍然可能会导致问题;

  4. 当代码中存在循环引用现象时," 引用计数 "算法就会导致问题;

  5. 解除变量的引用不仅有助于消除循环引用现象,而且对垃圾收集也有好处。为了确保有效的回收内存,应该及时解除不再使用的全局对象、全局对象属性以及循环引用变量的引用。

10. es6中const、let、var之间的区别?

  1. var定义的变量,作用域是整个封闭函数,是全域的;

    let定义的变量,作用域是在块级或者字块中;

  2. 变量提升:不论通过var声明的变量处于当前作用于的第几行,都会提升到作用域的最顶部。

    而let声明的变量不会在顶部初始化,凡是在let声明之前使用该变量都会报错(引用错误ReferenceError);

  3. 只要块级作用域内存在let它所声明的变量就会绑定在这个区域

  4. let不允许在相同作用域内重复声明(报错同时使用var和let,两个let)

const用来专门声明一个常量,它跟let一样作用于块级作用域,没有变量提升,重复声明会报错,不同的是const声明的常量不可改变,声明时必须初始化(赋值),const定义的对象可变。

const使用场景很广,包括常量、配置项以及引用的组件、定义的 “大部分” 中间变量等,都应该以cosnt做定义。反之就 let 而言,他的使用场景应该是相对较少的,我们只会在 loop(for,while 循环)及少量必须重定义的变量上用到他。

11. 闭包是什么?用let怎么实现闭包?

闭包是指有权访问另一个函数作用域中的变量的函数。

一个闭包就是一个没有释放资源的栈区,栈区内的变量处于激活状态。

在ES6中let实际是为js新增了块级作用域。

let声明的变量可以绑定在作用域中

面试题整理(华为)的评论 (共 条)

分享到微博请遵守国家法律