1. 原型,原型链,构造函数,原型对象的关系
1. prototype
每个函数都有一个prototype属性,被称为显式原型,里面包含了这个构造函数公共的方法
2._ _proto_ _
每个实例对象都会有_ _proto_ _属性,其被称为隐式原型
每一个实例对象的隐式原型_ _proto_ _属性指向自身构造函数的显式原型prototype
3. constructor
每个prototype原型都有一个constructor属性,指向它关联的构造函数。
4. 原型链
获取对象属性时,如果对象本身没有这个属性,那就会去他的原型_ _proto_ _上去找,如果还查不到,就去找原型的原型,一直找到最顶层(Object.prototype)为止。Object.prototype对象也有_ _proto_ _属性值为null。
构造函数
一般为大写字母开头,使用new操作符来实例化对象。
2. ajax的具体步骤
(1)创建ajax对象
(2)配置请求方式和请求地址以及是否异步请求
(3)浏览器向服务器发送请求
(4)服务器接受请求
(5)判断请求并响应数据
(6)服务器向浏览器返回数据
(7)浏览器渲染数据
// 1、
if (window.XMLHttpRequest) {
var xhr = new XMLHttpRequest();
console.log(xhr);
console.log(xhr.constructor);
} else {
// IE6-
var xhr = new ActiveXObject();
}
// 2、
// open("请求的方式","请求的地址",是否异步) ---后端人员给提供的
// true 异步 false 同步 默认是异步
xhr.open("GET", "ajax_info.txt", true);
// 3、
xhr.send();
// 4、
xhr.onreadystatechange = function () {
console.log(xhr);
console.log(xhr.readyState);//4
console.log(xhr.status);//200
// 5、
if (xhr.readyState == 4 && xhr.status == 200) {
// 6、
console.log(xhr.response);
// 7、
document.getElementById("box").innerText = xhr.response;
}
}
3. 如何实现深拷贝,深拷贝和浅拷贝的区别
浅拷贝: 将原对象的引用直接赋给新对象,新对象只是原对象的一个引用,而不复制对象本身,新旧对象还是共享同一块内存
深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”,新对象跟原对象不共享内存,修改新对象不会改到原对象
区别:深拷贝复制的是被复制数据或者对象的值,复制的数据或对象会在内存中重新分配内存空间,赋值的和被赋值的互不影响;浅拷贝赋值的是被复制数据或者对象的引用,复制的数据或对象通过引用指向被复制数据或者对象引用所指向的值。
第一种方法:let obj2 = JSON.parse(JSON.stringify(obj));
第二种方法是递归 function deepcopy(obj) {let obj2 = {};for (let key in obj) {if (obj[key] instanceof Object) {obj2[key] = deepcopy(obj[key]);
4. 什么是块级作用域
任何一对花括号({})中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域。
5. 什么是暂时性死区
如果区块(花括号)中存在`let`或const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域,**凡是在声明之前就使用这些变量,就会报错,所以在代码块内,使用`let`命令声明变量之前,该变量都是不可用的**
6. 箭头函数和function的区别是什么
(1)箭头函数是匿名函数,不能作为构造函数,不能使用new
箭头函数的定义比普通函数更加简洁清晰
(2)箭头函数内没有arguments,普通函数有
arguments是参数的意思,是一个类数组对象,里面放的就是函数的参数
(3)箭头函数的this,自己没有this,用的是父级所在环境的this
(4)箭头函数不能通过call()、apply()、bind()方法直接修改它的this指向。
(5)箭头函数没有原型属性
7. 链式调用原理是什么
一个对象中有多个方法,处于前面的每个方法都返回this,这样后面的方法就可以继续this环境下执行,就可以实现链式调用原理(返回自身在调用)
function Foo() {
}
Foo.prototype.set = function (name) {
this.name = name;
return this;
}
Foo.prototype.get = function (name) {
return this.name
}
console.log(Foo.prototype.set('lisi').get())
//list
8. 如何给vue的data动态添加或删除属性
方法一:vm.$set方法 :Vue.set(this.msg, 'spike', 'SPIKE')调用方法:Vue.set( target, key, value );Vue.set() 响应式新增与修改数据target:要更改的数据源(可以是对象或者数组)key:具体属性/位置value :重新赋的值返回值:设置的值。方法二:Vue-set方法 : this.$set(this.msg, 'spike', 'SPIKE')您还可以使用 vm.$set 实例方法,这也是全局 Vue.set 方法的别名:
9. 在组件上添加属性 **this.$set(this.data,"obj",value');**
删除属性**this.$delete(this.data,"obj",value');**
10. vue的缓存组件是哪个?用途是什么?
keep-alive
(1)组件缓存不是持久化,它只是在应用运行期间不会重新渲染,如果页面刷新还是会回到初始状态。(2) 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。(3) 要求被切换到的组件都有自己的名字,不论是通过组件的 name 选项还是局部/全局注册。(4)组件生命周期钩子和缓存
用处:在组件切换过程中 把切换出去的组件保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性
列表页面 ——进入详情页 —— 后退到列表页(缓存列表页的原来数据以及滚动位置)2、重新进入列表页面,获取最新的数据
当我们在切换路由需要保存失活组件的状态的时候需要用到,比如我浏览淘宝滑动的中间位置然后又去购物车页面,再回到首页的时候能够保存住我刚才滑动的位置
11. vue的动态加载组件是哪个?用于什么场景?
<component> 用来动态地挂载不同的组件 使用 is 属性来选择要挂载的组件。 让多个组件使用同一个挂载点,并动态切换,这就是动态组件配置路由,引入组件
按需加载。 import()可以在需要的时候,再加载某个模块。
12. 如何用递归组件实现一个多级菜单
递归组件遍历,利用v-if在层级不存在child情况下中止递归 给予每个层级菜单depth进行样式区别 设置每个层级菜单active当前选中菜单记录 默认参数actives设置,每个层级利用depth在数组(如:[1,2,3])默认值中获取自身默认值,若无则当前层级active为整个层级数组的第一个对象 每个层级的选中都会通过active的重新赋值,进而改变其子层级的data数组,直到最底层,所以,我们只记录最低层级的active变化向上传递改变,直到引用组件的最外层
( 通过使用 组件的name选项 对应的标签,实现多重循环的效果 同时,在调用组件自身的时候,要通过v-if实现条件渲染 防止因无限调用组件而导致栈溢出)
13. 有一个字符串‘a1b2c309pppkkk’要求重新排序为数字在后字母在前,且首字母大写,数字需要倒序排列,最后整体字符串去重。
使用split方法把字符串转换成数组,for循环遍历,加typeOf方法 把数字和字母分离出来,放在两个新数组,把字母数组下标为0的元素 使用toUpperCase方法 转换成大写字母,使用splice替换掉数组下标为0的 元素,数字数组使用reverse方法倒序,使用concat方法把两个数组拼接在一起, 使用join方法转换成数组,使用for循环和indexOf方法进行去重