2022前端⾯试学习笔记
⽬录
1、MVVM和MVC的区别
MVVM,Model-View-ViewModel,即模型-视图-视图模型。
【模型】指后端传递的数据, 【视图】指所看到的的页⾯。
【视图模型】是MVVM的核⼼,分为两个⽅向:1、【模型】->【视图】=》数据绑定 2、【视图】->【模型】=》DOM事件监听。两个⽅向都实现:双向绑定。总结:【视图】和【模型】之间不能直接通信,需要通过viewModel实现。
MVC,Model-View-controller,即模型-视图-控制器。
MVVM框架:VUE,在vue中:Model指的是js中的数据,⽐如对象、数组等。View指的是页⾯视图。viewModel指的是vue实例化对象。
从图中可以看出,当执⾏ new Vue() 时,Vue 就进⼊了初始化阶段,⼀⽅⾯Vue 会遍历 data 选项中的属性,并⽤
Object.defineProperty 将它们转为 getter/setter,实现数据变化监听功能;另⼀⽅⾯,Vue 的指令编译器Compile 对元素节点的指令进⾏解析,初始化视图,并订阅Watcher 来更新视图, 此时Wather 会将⾃⼰添加到消息订阅器中(Dep),初始化完毕。当数据发⽣变化时,Observer 中的 setter ⽅法被触发,setter 会⽴即调⽤ify(),Dep 开始遍历所有的订阅者,并调⽤订阅者的 update ⽅法,订阅者收到通知后对视图进⾏相应的更新。因为VUE使⽤Object.defineProperty⽅法来做数据绑定,⽽这个⽅法⼜⽆法通过兼容性处理,所以Vue 不⽀持 IE8 以及更低版本浏览器。另外,查看vue原代码,发现在vue初始化实例时, 有⼀个proxy代理⽅法,它的作⽤就是遍历data中的属性,把它代理到vm的
实例上,这也就是我们可以这样调⽤属性:vm.aaa等于vm.data.aaa。
2、JS中的基础类型
ES5中,6种基础类型:Number,String,Boolan,object,undefined,Null。
ES6中,新增⼀种Symbol 。这种类型的对象永不相等,即始创建的时候传⼊相同的值,可以解决属性名冲突的问题,做为标记。新增BigInt 可以表⽰任意⼤⼩的整数。
3、JS中==和===区别
==相同,===严格相同。
4、JS中的深拷贝浅拷贝区别
深拷贝实现⽅法有两种:
1)JSON.stringify/parse
2)利⽤递归来实现每⼀层都重新创建对象并赋值
function deepClone(source){
const targetObj = structor === Array ? [] : {}; // 判断复制的⽬标是数组还是对象  for(let keys in source){ // 遍历⽬标
if(source.hasOwnProperty(keys)){
if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归⼀下
targetObj[keys] = source[keys].constructor === Array ? [] : {};
targetObj[keys] = deepClone(source[keys]);
}else{ // 如果不是,就直接赋值
targetObj[keys] = source[keys];
}
}
}
return targetObj;
}
const deepCopy = function (src) {
if (src instanceof Array) {
return src.map(e => deepCopy(e));
} else if (src instanceof Object) {
const target = {};
Object.keys(src).forEach(key => {
if (src[key] instanceof Date) {
target[key] = new Date(src[key].getTime());
} else if (src[key] instanceof Object) {
target[key] = deepCopy(src[key]);
} else {
target[key] = src[key];
}
});
return target;
}
return src;
};
5、原型、构造函数和实例的理解
6、什么是闭包闭包解决了什么问题闭包导致了什么问题
根据MDN中⽂的定义,闭包的定义如下:
在JavaScript中,每当创建⼀个函数,闭包就会在函数创建的同时被创建出来。可以在⼀个内层函数中访问到其外层函数的作⽤域。
也可以这样说:
闭包是指那些能够访问⾃由变量的函数。⾃由变量是指在函数中使⽤的,但既不是函数参数也不是函数的局部变量的变量。闭包=函数+函数能够访问的⾃由变量。
闭包就是能够读取其他函数内部变量的⼀个函数。
简单的说闭包是解决了函数内变量暴露给函数外访问。
就是为了解决突破函数作⽤域的限制才有了闭包这种概念。
闭包可能导致内存泄露,即函数执⾏完成后内部变量引闭包存在原因还可访问
例:
function print(fn) {
const a = 200;
fn();
}
const a = 100;
function fn() {
console.log(a);
}
print(fn); //100
闭包:⾃由变量的查,是在函数定义的地⽅,向上级作⽤域查。不是在执⾏的地⽅。
7、call、apply、bind实现
call
call()⽅法在使⽤⼀个指定的this值和若⼲个指定的参数值的前提下调⽤某个函数或⽅法。
var obj = {
value: "123".
};
function fn() {
console.log(this.value);
}
fn.call(obj); //123
通过call⽅法我们做到了以下两点:
1)call改变了this的指向,指向到obj。
2)fn函数执⾏了。
⾃⼰写call⽅法:
var obj = {
value: "123",
fn: function () {
console.log(this.value);
},
};
obj.fn(); //123
这时候 this 就指向了 obj ,但是这样做我们⼿动给 obj 增加了⼀个 fn 属性,这显然是不⾏的,不⽤担⼼,我们执⾏完再使⽤对象属性的删除⽅法(delete)不就⾏了?
obj.fn = fn;
obj.fn();
delete obj.fn;
根据这个思路,我们可以写出来:
var obj = {
value: "vortesnail",
};
function fn(t) {
console.log(this.value);
console.log(t)
}
Call = function (context) {
console.log(111,context);
var obj2 = {
value: "test"
}
/
/ 判断调⽤对象
if (typeof this !== "function") {
throw new Error("Type error");
}
// ⾸先获取参数
console.log(333,[...arguments]);
let args = [...arguments].slice(1);
console.log(222,args);
let result = null;
// 判断 context 是否传⼊,如果没有传就设置为 window        context = context || window;
// 将被调⽤的⽅法设置为 context 的属性
/
/ this 即为我们要调⽤的⽅法
console.log(444, this);
context.fn = this;
console.log(555, this);
// 执⾏要被调⽤的⽅法
result = context.fn(...args);
// 删除⼿动增加的属性⽅法
delete context.fn;
// 将执⾏结果返回
return result;
box sizing};
//  vortesnail
// test
call、apply、bind传参格式不同

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。