js基础面试题整理(包含ES5,ES6)

写一下 Javascript 的原始类型

原始类型:number,string,boolean,null,undefined

引用类型:object

Typeof null // 输出object(null 被认为是对象的占位符)

例举3种强制类型转换和2种隐式类型转换?

强制(parseInt, parseFloat, number)
隐式(== ===)

parseInt() 函数可解析一个字符串,并返回一个整数。
parseFloat() 函数可解析一个字符串,并返回一个浮点数。
Number() 函数把对象的值转换为数字。

注意使用parseFloat()时:
1.字符串中只返回第一个数字。
2. 开头和结尾的空格是允许的。
3. 如果字符串的第一个字符不能被转换为数字,那么 parseFloat() 会返回 NaN。

列举鼠标事件。

onClick 鼠标点击事件
onDblClick 双击事件
onMouseOver 鼠标经过
onMouseOut 鼠标移出
onMouseDown 鼠标上的按钮被按下了
onMouseUp 鼠标按下后,松开时激发的事件

表单相关事件
onFocus 获得焦点
onBlur 失焦
onChange 改变文本框内容触发
onSubmit 一个表单被提交时触发的事件

数组方法pop() push() unshift() shift()

push() 数组尾部添加
pop()尾部删除
unshift() 数组头部添加
shift()头部删除

数组的截取和合并

concat() 合并数组

var arr = [1,2,3];
var arr1 = [4,5,6];
var arr2 = arr.concat(arr1);
console.log(arr2); // [1,2,3,4,5,6];

slice() 来截取数组。

var arr = [1,2,3];
console.log(arr.slice(0,1);); // [1];
// slice方法接受两个参数,一个从哪里开始,一个是到哪里结束(但是不包括这个结束的元素本身)。如果是负数,就从倒数第几个。

删除指定数组

splice()从数组中添加/删除项目,然后返回被删除的项目

var arr = [1,2,3];
arr.splice(0,1); //从数组下标0开始,删除1个元素
console.log(arr); // [2,3];
// 接受两个参数,第一个是index,数组开始的下标,第二个是len,要删除的长度

数组元素的排序

reverse()颠倒数组中元素的顺序

let a = [1,2,3];
a.reverse(); 
console.log(a); // [3,2,1]

sort()方法对数组元素进行排序,并返回这个数组。
sort排序常见用法:数组元素为数字的升序、降序:

var array = [10, 1, 3, 4,20,4,25,8];
array.sort(function(a,b){
    
    
 return a-b; //升序
});
console.log(array); // [1,3,4,4,8,10,20,25];
var array = [10, 1, 3, 4,20,4,25,8];
array.sort(function(a,b){
    
    
 return b-a; //降序
});
console.log(array); // [25,20,10,8,4,4,3,1];

数组转字符串

join()方法用于把数组中的所有元素通过指定的分隔符进行分隔放入一个字符串,返回生成的字符串

let a= ['hello','world'];
let str=a.join(); // 'hello,world'
let str2=a.join('+'); // 'hello+world'

关于数组具体实例可参考 js中数组的操作方法

JS中提取字符串的方法

substring(start,end)表示从start到end之间的字符串,包括start位置的字符但是不包括end位置的字符。

var src="images/off_1.png";
alert(src.substring(7,10));//off

字符串实现倒序输出

newStr = arr.split('').reverse().join('')

数组去重?

此题看着简单,但要想面试官给你高分还是有难度的。至少也要写出几种方法
js

var array=['12','32','89','12','12','78','12','32'];
    // 最简单数组去重法
    //新建一个空的结果数组,for 循环原数组,判断结果数组是否存在当前元素,
    //如果有相同的值则跳过,不相同则push进数组。
    function unique1(array){
    
    
        var n = []; //一个新的临时数组
        for(var i = 0; i < array.length; i++){
    
     //遍历当前数组
            if (n.indexOf(array[i]) == -1)
                n.push(array[i]);
        }
        return n;
    }
    arr=unique1(array);
    // 速度最快, 占空间最多(空间换时间)
    function unique2(array){
    
    
        var n = {
    
    }, r = [], type;
        for (var i = 0; i < array.length; i++) {
    
    
            type = typeof array[i];
            if (!n[array[i]]) {
    
    
                n[array[i]] = [type];
                r.push(array[i]);
            } else if (n[array[i]].indexOf(type) < 0) {
    
    
                n[array[i]].push(type);
                r.push(array[i]);
            }
        }
        return r;
    }
    //数组下标判断法
    function unique3(array){
    
    
        var n = [array[0]]; //结果数组
        for(var i = 1; i < array.length; i++) {
    
     //从第二项开始遍历
            if (array.indexOf(array[i]) == i) 
                n.push(array[i]);
        }
        return n;
    }

es6

es6方法数组去重
arr=[...new Set(arr)];
es6方法数组去重,第二种方法
function dedupe(array) {
    
    
  return Array.from(new Set(array));       //Array.from()能把set结构转换为数组
}

数组的遍历?

一般有3种方法遍历数组:

  1. for循环
  2. for each ( ES5 新增)
  3. for… in

1.1 使用普通for循环遍历数组

var arr = [50, 20, 10, 5, 15, 6];       
for(var i = 0; i < arr.length; i++){
    
        //数组长度多长,就遍历多少次。  循环变量作为数组的下标
  console.log(arr[i]);
}

2.1 使用for …each遍历数组

ES5为每个数组新增了一个方法 array.forEach(function) ,使用这个方法,可以自动帮我们遍历数组中的所有元素

var arr = [50, 20, 10, 5, 15, 6];
//调用数组的forEach方法,传入一个匿名函数
//匿名函数接受两个参数:   参数1--迭代遍历的那个元素  参数2:迭代遍历的那个元素的下标
//可以在匿名函数内部书需要的代码
arr.forEach( function(element, index) {
    
    
  alert(element);
});

3.1 使用 for…in 循环遍历数组

for-in 语句是一种精准的迭代语句,可以用来枚举对象的属性和数组的元素。示例:

var arr = [50, 20, 10, 5, 15, 6];
// 每循环一轮,都会把数组的下标赋值给变量index,然后num就拿到了每个元素的下标。 
//注意:这里index是元素的下标,不是与元素
//对数组来说,index从从0开始顺序获取下标
for (var index in arr) {
    
    
  console.log(num);  //循环输出: 0 1 2 3 4 5
}
//这里var 关键字也是可以省略的,但是不建议省略。
for(i in arr){
    
    
  console.log(arr[i]);
}

列举出两个伪数组,如何转化成数组?

伪数组:有函数三要素(下标,元素,长度),没有数组的api

        var weiArr = {
    
    
            0: 22,
            1: 44,
            2: 55,
            3: 77,
            4: 99,
            length: 5
        }
 **方法一:声明一个空数组,遍历伪数组,将伪数组中的元素添加到真数组中**
        var arr=[];
        for(var i = 0;i<weiArr.length;i++){
    
    

            arr.push(weiArr[i]);
        }
**方法二(常用):arr.push.apply(arr,伪数组)**
        var arr=[];
        arr.push.apply(arr,weiArr);
        //不需要修改push的this,只是利用apply的传参特点
        console.log(arr);
**方法三 arr.slice(0):如果是固定参数0,则会返回数组自身**
//call(weiArr,0)  : 把slice()中的this 从原型对象 修改为 伪数组
        weiArr=Array.prototype.slice.call(weiArr,0)

IE和标准下有哪些兼容性的写法

var ev = ev || window.event
document.documentElement.clientWidth || document.body.clientWidth
Var target = ev.srcElement||ev.target

ajax请求的时候get 和post方式的区别

一个在url后面 ,一个放在虚拟载体里面
get有大小限制(只能提交少量参数)
安全问题
应用不同 ,请求数据和提交数据

ajax请求时,如何解析json数据

使用JSON.parse

var jsonDate = '{ "name":"hello","age":23 }';
var jsonObj = JSON.parse( jsonDate ); 

如何中断ajax请求?

一种是设置超时时间让ajax自动断开,另一种是手动停止ajax请求,其核心是调用XML对象的abort方法,ajax.abort()

事件委托是什么??

利用事件冒泡的原理,让自己的所触发的事件,让他的父元素代替执行!

事件委托利用事件冒泡原理来实现,何为事件冒泡?就是事件从最深节点开始,然后逐步向上传播事件,比如页面有一个节点树,div > ul > li > a, 给最里面a加一个click点击事件,那么这个事件就会一层层往外执行,执行顺序 a > li> ul > div,既然有这样一个机制,那么我们给最外面的div加点击事件,那么里面的ul,li,a做点击事件的时候,都会冒泡到最外层的div,所以都会触发,这就是事件委托,委托他们的父系级代为执行事件。

如何阻止事件冒泡?

event.stopPropagation();

<script type="text/javascript">
        $(function() {
    
    
            $("#hr_three").click(function(event) {
    
    
                event.stopPropagation();
            });
        });
<script>

可参考:JS如何阻止事件冒泡

如何阻止默认事件?

1.return false; 2.event.preventDefault();

//return false; 事件处理过程中,阻止了事件冒泡,也阻止了默认行为
<script type="text/javascript">
$(function() {
    
    
  $("#hr_three").click(function(event) {
    
    
    return false;
  });
});
<script>
//event.preventDefault(); 事件处理过程中,不阻击事件冒泡,但阻击默认行为
<script type="text/javascript">
$(function() {
    
    
  $("#hr_three").click(function(event) {
    
    
    event.preventDefault();
  });
});
<script>

Javascript的事件流模型都有什么?

先解释下事件流是什么:当你在页面触发一个点击事件后,页面上不仅仅有一个元素响应该事件而是多个元素响应同一个事件,因为元素是在容器中的。事件发生的顺序就是事件流,不同的浏览器对事件流的处理不同。

“事件冒泡”:事件开始由最具体的元素接收,然后逐级向上传播
“事件捕捉”:事件由最不具体的节点先接收,然后逐级向下,一直到最具体的
“DOM事件流”:三个阶段:事件捕捉,目标阶段,事件冒泡

添加 删除 替换 插入到某个接点的方法?

(1)创建节点
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点

(2)添加、移除、替换、插入
appendChild() //最后1个子节点之后添加一个新子节点
removeChild() //删除子节点
replaceChild() //替换子节点
insertBefore() //在已有的子节点前插入一个新节点

(3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性

遍历A节点的父节点下的所有子节点

这题考查原生的js操作dom,属于非常简单的基础题,但长时间使用mvvm框架,可能会忘记

<script>
    var b=document.getElementById("a").parentNode.children;
    console.log(b)
</script>

document load 和document ready的区别?

document.onload 是在结构和样式,外部js以及图片加载完才执行js。
document.ready是dom树创建完成就执行的方法,原生种没有这个方法,jquery中有 $().ready(function)

什么是回调函数?

  把a函数作为b函数的参数,传递给b函数,则这个a函数就叫做b的回调函数
var a = function(){
    
    

}
var b = function(callback){
    
    

}
b(a); //把a函数作为参数传递给b函数,则a就是b的回调函数

看下面代码,给出输出结果。

for(var i = 1; i <= 3; i++){
    
      //建议使用let 可正常输出i的值
  setTimeout(function(){
    
    
      console.log(i);   
  },0); 
};
//答案:4 4 4。
//原因:Javascript事件处理器在线程空闲之前不会运行。

回答以下代码,alert的值分别是多少?

<script>
     var a = 100;  
     function test(){
    
      
        alert(a);  
     a = 10;  //去掉了var 就变成定义了全局变量了
        alert(a);  
}  
test();
alert(a);
</script>
//正确答案是: 100, 10, 10

具体可查询:js变量的作用域详解

以下代码执行结果?

var uname = 'jack'
function change() {
    
    
    alert(uname) // ?
    var uname = 'lily'
    alert(uname)  //?
}
change()
//分别alert出 undefined,lily,(变量声明提前问题)

javaScript的2种变量范围有什么不同?

全局变量:当前页面内有效
局部变量:函数方法内有效

如何获取javascript三个数中的最大值和最小值??

Math.max(a, b ,c) //最大值
Math.min(a, b ,c) //最小值

javascript是面向对象的,怎么体现javascript的继承关系???

使用prototype原型来实现。

一个简单的例子:

var A =function(){
    
    

      }
      A.prototype = {
    
    
         v : 5,
         tmp : 76,
         echo : function(){
    
    console.log(this.tmp);},
      }  //v、tmp、echo 都是属于A的原型,
      var b = new A();
      b.echo();  //但是此处会发现b也可以调用A的所有原型,而b并没有声明任何echo()方法
      

程序中捕获异常的方法?

try{
    
    
 
}catch(e){
    
    
 
}finally{
    
    
 
}

null和undefined的区别

在JavaScript中,null 和 undefined 几乎相等

console.log(null==undefined);    //true  因为两者都默认转换成了false
console.log(null===undefined);    //false   "==="表示绝对相等,null和undefined类型是不一样的,所以输出“false”
console.log(typeof undefined);    //"undefined"  
console.log(typeof null);       //"object"  

可以发现:null和undefined 两者相等,但是当两者做全等比较时,两者又不等。
原因:类型不一样
null: Null类型,代表“空值”,代表一个空对象指针,使用typeof运算得到 “object”,所以你可以认为它是一个特殊的对象值。
undefined: Undefined类型,当一个声明了一个变量未初始化时,得到的就是undefined。

那到底什么时候是null,什么时候是undefined呢???

null表示"没有对象",即该处不应该有值。典型用法是:

(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。

undefined表示缺少值,即此处应该有值,但没有定义。典型用法是:

(1)定义了形参,没有传实参,显示undefined

(2)对象属性名不存在时,显示undefined

(3)函数没有写返回值,即没有写return,拿到的是undefined

(4)写了return,但没有赋值,拿到的是undefined

写一下 js的比较运算符,逻辑运算符

比较运算符:

>    大于
<    小于
>=   大于或等于
<=   小于或等于
==   等于
!=   不相等
===  值相等并且类型相等
!=== 值不相等或类型不相等

逻辑运算符:

在这里插入图片描述
比较运算符和逻辑运算符用于测试true和false

== 和 === 的区别

=是赋值的意思;==是判断的意思;===也是判断,但是它比==判断更严谨一点,他的判断必须什么都相等,比如类型,值。
比如alert(1===‘1’);将返回false,因为前面的1是数字类型,后面的1是字符串类型

JS中的let和var的区别

  1. 使用var声明的变量,其作用域为该语句所在的函数内,且存在变量提升(如果是在任何函数外面,则是全局执行上下文,如果在函数里面,则是当前函数执行上下文。换句话说,var 声明的变量的作用域只能是全局或者整个函数块的)
  2. 使用let声明的变量,其作用域为该语句所在的代码块内,不存在变量提升
  3. let不允许在相同作用域内,重复声明同一个变量

可参考: 前端面试题:JS中的let和var的区别

let 与 const 异同

const 与 let 很类似,都具有上面提到的 let 的特性,唯一区别就在于 const 声明的是一个只读变量声明之后不允许改变其值。因此,const 一旦声明必须初始化,否则会报错。

let a;
const b = "constant"

a = "variable"
b = 'change' // TypeError: Assignment to constant variable

this在Es5 和 Es6的区别

this在ES5中默认指向window对象,在ES6的vue中默认指向Vue实例,基本没什么区别,都是指向最顶层的对象

this在函数中的时候,指向的是这个函数的作用域,当在函数中出现回调等情况的时候,回调函数中的this作用域会变成指向该回调函数,因此一般会在函数中使用 var that = this来保存this。

例如ES5中 this 的指向

var x = function(){
    
    
		   this.a = 'a';
		   this.b = 'b';
		   this.c = {
    
    
		        a:'1',
		        b:function(){
    
    return this.a}
		    }  
		};
		console.log(new factory().c.b()); 
		//结果:1
		//调用函数返回值为1,this 的指向是该函数被调用的对象,也就是说函数被调用的时候,this 指向的是对象调用的这个函数。

而ES6新引入了箭头函数,在箭头函数中,this指向上下文对象,因此可以不用再写 var that=this了

可参考:浅析this在ES5 和 ES6中使用的区别

什么是js闭包??闭包作用以及优缺点?

可参考:闭包的作用和优缺点。闭包作用这里讲的很详细!!!!!!

简而言之,函数里面的一些变量和函数表达式,可以通过里面的函数访问这个函数的变量,防止全局变量的污染以及变量的改变

作用:

1.读取函数内部的变量;
2.这些变量的值始终保持在内存中,不会在外层函数调用后被自动清除。

详细描述就是:
涉及到变量的生命周期问题了,函数内部定义的变量属于局部变量,局部变量的生命周期是:当它所在的函数被调用的时候,就是开始,当调用执行一旦结束,局部变量就会被释放,当我们需要函数内部变量时,他已经被释放了,读取不到了,这个时候怎么解决?我们就要想办法延长他的生命周期
闭包的目的也可以说就是这个,延长局部变量的生命周期,当函数执行完毕以后,局部变量不可以被内存释放,然后让外部可以访问到这个变量

优点:

1:变量长期驻扎在内存中;
2:避免全局变量的污染;
3:私有成员的存在 ;

闭包的坏处:

闭包使函数内部的变量不能被内存释放,这些变量就会占用内存,内存消耗大,可能会导致内存泄露
解决这个问题的办法就是在不使用这些变量时,及时把不需要的局部变量全部删除

promise是什么?怎么使用??

Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息。

promise是一个对象,从它可以获取异步操作的消息;promise有三种状态: 等待,成功,失败,当promise状态发生改变,就会触发.then()里的响应函数处理后续步骤;状态一旦改变,就不会再变。创造promise实例后,它会立即执行。

当Promise启动后,
满足成功的条件时我们让状态从等待变成成功
满足失败的条件时我们让状态从等待变成失败

应用场景:
1、解决回调地狱 (通过.then .catch方法,处理ajax返回的结果,用链式调用的方式解决回调地狱)
2、将异步操作队列化,按照期望的顺序执行,返回符合预期的结果(.than(1).than(2).than(3) 顺序执行)

Promise使用:

  //拿ajax的例子来做一下Promise封装
  function myAjax(url) {
    
    
    return new Promise((resolve, reject) => {
    
    
      $.ajax({
    
    
        url: url,
        success: function(data) {
    
    
          //成功则返回data数据
          resolve(data)
        },
        error: function(err) {
    
    
          //失败则返回错误信息err
          reject(err)
        }
      });
    })
  }

  /*来来来,看好了,
  封装好ajax之后我们就可以去进行请求数据了*/
  let res1 = myAjax('xxxx/api/xxxx');
  let res2 = res1.then(myAjax('xxxx/api/xxxx'));
  let res3 = res2.then(myAjax('xxxx/api/xxxxx'));

可参考:(前端必会)理解异步和Promise的使用
js promise看这篇就够了

async/await
async/await是 JS 中编写异步或非阻塞代码的新方法。它建立在Promises之上,让异步代码的可读性和简洁度都更高。

为什么代码可读性变得更高了?因为页面上可能有多个promise的.then()方法,导致代码看起来很复杂,此时可以使用 await代替.then(),让代码更少,更简洁(async/await 的优 势:可以很好地处理 then 链)

(1)建立在Promises之上,相对于 Promise 和回调,它的可读性和简洁度都更高
(2)它是基于promise构建的,比如async 定义的函数,返回的还是一个promise对象

可参考:vue中异步函数async和await的用法

js的原型链

(1)简单理解就是原型组成的链,对象的__proto__是它的原型,而原型也是一个对象,也有__proto__属性,原型的__proto__又是原型的原型,就这样可以一直通过__proto__想上找,这就是原型链,当向上找找到Object的原型的时候,这条原型链就算到头了。
(2)当访问对象a的b属性的时候,首先会查找当前对象的b属性,如果没有,然后依次按照prototype往上找直到找到Object.prototype为止,没有则返回undefined,所以说无处不在。
(3)可以类比于冒泡事件,从当前对象开始,通过_proto__属性可以一直找到它的父级,父级也没有__proto__属性,可以继续往上找,直到找到object为止
(4)__proto__是对象的属性。 prototype是函数方法的属性

说一下继承的几种方式及优缺点?

说比较经典的几种继承方式并比较优缺点就可以了

  1. 借用构造函数继承,使用call或apply方法,将父对象的构造函数绑定在子对象上
  2. 原型继承,将子对象的prototype指向父对象的一个实例
  3. 组合继承

原型链继承的缺点
字面量重写原型会中断关系,使用引用类型的原型,并且子类型还无法给超类型传递参数。

借用构造函数(类式继承)
借用构造函数虽然解决了刚才两种问题,但没有原型,则复用无从谈起。

组合式继承
组合式继承是比较常用的一种继承方法,其背后的思路是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又保证每个实例都有它自己的属性。

说一下同步和异步

同步会阻塞,异步不会阻塞

同步:程序运行从上而下,浏览器必须把这个任务执行完毕,才能继续执行下一个任务

异步:程序运行从上而下,浏览器任务没有执行完,但是可以继续执行下一行代码,当被调用者得到结果之后会通过回调函数主动通知调用者。

js延迟加载的方式有哪些?

defer 属性在<script>元素中设置 defer属性,等于告诉浏览器立即下载,但延迟执行,只适用于外部脚本文件。
和async属性、动态创建DOM方式(创建script,插入到DOM中,加载完毕后callBack)
使用setTimeout延迟方法
让JS最后加载(把js外部引入的文件放到页面底部,来让js最后引入,从而加快页面加载速度)

希望获取到页面中所有的checkbox怎么做?(不使用第三方框架)?

var inputs = document.getElementsByTagName("input");//获取所有的input标签对象
var checkboxArray = [];//初始化空数组,用来存放checkbox对象。
for(var i=0;i<inputs.length;i++){
    
    
  var obj = inputs[i];
  if(obj.type=='checkbox'){
    
    
     checkboxArray.push(obj);
  }
}

写一个function,清除字符串前后的空格。(兼容所有浏览器)?

String.prototype.trim= function(){
    
    

return this.replace(/^\s+/,"").replace(/\s+$/,"");

}

Cookie在客户机上是如何存储的

Cookies就是服务器暂存放在你的电脑里的文本文件,好让服务器用来辨认你的计算机。当你在浏览网站的时候,Web服务器会先送一小小资料放在你的计算机上,Cookies 会帮你在网站上所打的文字或是一些选择都记录下来。当下次你再访问同一个网站,Web服务器会先看看有没有它上次留下的Cookies资料,有的话,就会依据Cookie里的内容来判断使用者,送出特定的网页内容给你。

ajax原理

创建一个XHR对象,并发送异步请求,接着监听服务器响应结果,并把它渲染在页面上

什么是json??

(1)JSON 是一种轻量级的数据交换格式;采用键值对的方式,易于阅读和编写,同时也易于机器解析和生成。
(2)JSON 是独立于语言的,也就是说不管是什么语言,都可解析为json,只需按照json规则来就行。
(3)JSON的语法表示三种类型值,简单值(字符串,数值,布尔值,null),数组对象

git使用过程中,如果你在开发着业务,突然另一个分支有一个bug要改,你怎么办

git stash       //将目前还不想提交的但是已经修改的内容进行保存至暂存区
git stash pop   //将所有暂存区的内容取出来
//过程:当正在dev分支上开发某个项目,这时项目中出现一个bug,需要紧急修复,但是正在开发的内容只是完成一半,还不想提交,这时可以用git stash命令将修改的内容保存至堆栈区,然后顺利切换到hotfix分支进行bug修复,修复完成后,再次切回到dev分支,从堆栈中恢复刚刚保存的内容。

解释一下 JavaScript的同源策略

同源策略是客户端脚本(尤其是Javascript)的安全度量标准,为了防止某个文档或脚本从多个不同源装载
同源策略是一种安全协议,指一段脚本只能读取来自同一来源的窗口和文档的属性
所谓同源就是同域名、同协议、同端口,只有同源的地址才能相互通过ajax方式请求

为什么要有同源限制

我们举例说明:比如一个黑客程序,他利用IFrame把真正的银行登录页面嵌到他的页面上,当你使用真实的用户名,密码登录时,他的页面就可以通过Javascript读取到你的表单中input中的内容,这样用户名,密码就轻松到手了。

为什么要组件化开发??

有时候页面代码量太大,逻辑太多或者同一个功能组件在许多页面均有使用,维护起来相当复杂,这个时候,就需要组件化开发来进行功能拆分、组件封装,已达到组件通用性,增强代码可读性,维护成本也能大大降低

组件化开发的优点??

很大程度上降低系统各个功能的耦合性,并且提高了功能内部的聚合性。这对前端工程化及降低代码的维护来说,是有很大的好处的,耦合性的降低,提高了系统的伸展性,降低了开发的复杂度,提升开发效率,降低开发成本

图片的预加载和懒加载

预加载:就是在网页全部加载之前,提前加载图片,当用户需要查看时可直接从本地缓存中渲染,以提供给用户更好的体验,减少等待的时间。
懒加载:延迟加载图片或符合某些条件时才加载某些图片。

两种技术的本质:两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。预加载则会增加服务器前端压力,懒加载对服务器有一定的缓解压力作用。

猜你喜欢

转载自blog.csdn.net/weixin_45811256/article/details/109805184