js常见问题

1.get请求传参长度的误区

http协议中对get请求传参长度并没有作出限制。而是浏览器和服务器对请求地址整体的URI有限制,并不是对局部的传参有限制。

HTTP 协议 未规定 GET 和POST的长度限制
GET的最大长度显示是因为 浏览器和 web服务器限制了 URI的长度
是限制的是整个 URI 长度,而不仅仅是你的参数值数据长度

2.补充get和post请求在缓存方面的区别

get请求类似于查找的过程,用户获取数据,可以不用每次都与数据库连接,所以可以使用缓存。post不同,post做的一般是修改和删除数据的工作,所以必须与数据库交互,所以不能使用缓存。因此get请求适合于请求缓存。

3.说一下图片的懒加载和预加载

可参考https://www.jianshu.com/p/4876a4fe7731

4.mouseover和mouseenter区别

mouseover/mouseout事件支持冒泡,绑定的事件会冒泡到子标签上。
mouseenter/mouseleave事件则只针对所绑定的标签,不会冒泡到子标签上。

mouseover:当鼠标指针位于元素上方时,会发生 mouseover 事件。
mouseenter:当鼠标指针穿过元素时,会发生 mouseenter 事件。

从这里的一个小插曲上,我们应该可以看出,mouseenter是穿过,所以只能触发一次改事件,而mouseover是位于上方,
可以想下,如果给div设定了一个mouseover事件,其子孙后代都可以响应改事件,so...一旦鼠标从父级进入自己也会触发这个效果,当从子集回到父级也会触发这种效果。
所以,你可以这么理解:mouseenter事件只作用于目标元素,而mouseover最用于目标元素及其后代元素。
例子:http://www.aijquery.cn/Html/jqueryrumen/129.html

5.异步加载js的方法

方案一:<script>标签的async="async"属性(详细参见:script标签的async属性)
点评:HTML5中新增的属性,Chrome、FF、IE9&IE9+均支持(IE6~8不支持)。此外,这种方法不能保证脚本按顺序执行。
方案二:<script>标签的defer="defer"属性
点评:兼容所有浏览器。此外,这种方法可以确保所有设置defer属性的脚本按顺序执行。
方案三:动态创建<script>标签
其他方案:
a.XHR注入(通过XMLHttpRequest对象来获取JS,然后创建一个script元素插入到DOM结构中);
b.ajax eval(使用ajax得到脚本内容,然后通过eval(xmlhttp.responseText)来运行脚本);
c.iframe等

6.ajax解决浏览器缓存问题

我们在做项目中,一般提交请求都会通过ajax来提交,但是测试的时候发现,每次提交后得到的数据都是一样的,调试可以排除后台代码的问题,所以问题肯定是出在前台

每次清除缓存后,就会得到一个新的数据,所以归根到底就是浏览器缓存问题。纠结了很久,终于解决了,在这里总结一下。

我们都知道ajax能提高页面载入的速度主要的原因是通过ajax减少了重复数据的载入,也就是说在载入数据的同时将数据缓存到内存中,一旦数据被加载其中,只要我们没有刷新页面,这些数据就会一直被缓存在内存中,当我们提交 的URL与历史的URL一致时,就不需要提交给服务器,也就是不需要从服务器上面去获取数据,虽然这样降低了服务器的负载提高了用户的体验,但是我们不能获取最新的数据。为了保证我们读取的信息都是最新的,我们就需要禁止他的缓存功能。

解决方案有如下几种:

1、在ajax发送请求前加上 anyAjaxObj.setRequestHeader("If-Modified-Since","0")。

2、在ajax发送请求前加上 anyAjaxObj.setRequestHeader("Cache-Control","no-cache")。

3、在URL后面加上一个随机数: "fresh=" + Math.random();。

4、在URL后面加上时间搓:"nowtime=" + new Date().getTime()

7.js的节流和防抖

https://segmentfault.com/a/1190000018428170

8.eval是做什么的?

1.作用:
把字符串参数解析成JS代码并运行,并返回执行的结果。

eval("2+3");//执行加运算,并返回运算值
eval("var age=10");//声明一个age变量

2.缺陷:
应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。

3.使用场景:
由JSON字符串转换为JSON对象的时候可以用eval,例如:

varjson="{name:'Mr.CAO',age:30}";
varjsonObj=eval("("+json+")");
console.log(jsonObj);

9.如何理解前端模块化&说一下Commonjs,AMD,CMD

https://www.cnblogs.com/lvdabao/p/js-modules-develop.html#!comments
https://blog.csdn.net/heyue_99/article/details/54894719

10.实现一个once函数,传入函数参数只执行一次

闭包


function test () {console.log('test')}
 
var once = function (fn) {
  var isFirst = true;
  return function () {
    if (isFirst) {
      isFirst = !isFirst;
      fn();
    }
  };
};
 
var b = once(test);
b(); // 'test'
b(); // nothing

11.如何实现一个私有变量,用getName方法可以访问,不能直接访问

闭包

        (function (window) {
            var name = '我是私有变量,其他人都找不到我'
            window.getName = function () {
                return name
            }
        })(window)
        console.log(getName()) //'我是私有变量,其他人都找不到我'
        console.log(name) // undefined
        console.log(window.name) //undefined

12.如何让时间先冒泡后捕获

根据w3c标准,应先捕获再冒泡。若要实现先冒泡后捕获,给一个元素绑定两个addEventListener,其中一个第三个参数设置为false(即冒泡),另一个第三个参数设置为true(即捕获),调整它们的代码顺序,将设置为false的监听事件放在设置为true的监听事件前面即可。

13.自己实现一个bind函数

 function bind(fn,context) {
        return function () {
            return fn.apply(context,arguments);
        }
   }

14.用setTimeout来实现setInterval

参考:https://blog.csdn.net/baidu_24024601/article/details/51862488

setTimeout(function(){

    //do something

    setTimeout(arguments.callee,interval);
},interval)

15.js怎么实现一次加载一张图片,加载完后再加载下一张?

https://www.nowcoder.com/questionTerminal/860f6d017a2e4d4c810b3445d601296d
首先html中的图片不要加路径。。src为空
把图片路径写在一个数组里 var a_imgurl=["a1.png","a2.png","a3.png","a4.png"];
然后var a_img=document.getElementsByTagName("img");
var i=0;
function f_load_img(n){
if(n>a_imgurl.length-1)return;
a_img[n].src=a_imgurl[n];
a_img[n].onload=function(){
f_load_img(++i)
}
}f_load_img(i)

16.如何实现sleep的效果 es5/es6

参考:https://blog.csdn.net/clschen/article/details/51727599
es5:

setTimeout(function(){ alert("Hello"); }, 3000);

es6:

// https://zeit.co/blog/async-and-await
function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

// 用法
sleep(500).then(() => {
    // 这里写sleep之后需要去做的事情
})

17.实现js中所有对象的深度克隆(包装对象,Date对象,正则对象)

https://blog.csdn.net/dadadeganhuo/article/details/86618630

18.箭头函数中this指向举例

https://blog.csdn.net/liwusen/article/details/70257837

19.js判断类型

1.typeof
判断基本数据类型,返回boolean,undefind,string,number,function,object的字符串。
2.instanceof
基于原型链进行判断。obj instanceof Object,左边操作数obj为对象,右边操作数Object为函数对象或者是函数构造器。
实质就是:instanceof操作符判断左操作数对象的原型链上是否有右边这个构造函数的prototype属性,也就是说指定对象是否是某个构造函数的实例,最后返回布尔值,这个对整个原型链上的对象都是有效的,由于instanceof对整个原型链上的对象都有效,因此同一个实例对象,可能会对多个构造函数都返回true!
3.constructor


如果我创建一个对象,更改它的原型,这种方式也变得不可靠了。
4.Object.prototype.toString.call()-----最可靠
为什么一定要用Object上的原型方法?
这是因为toString为Object的原型方法,而Array 、Function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(Function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串.....),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object上原型toString方法。

扩充:如何判断一个对象是不是数组?

1.Arrays.isArray(obj) //true/false
2.Object.prototype.toString.call(obj) //"[object Array]"

20.数组去重

1.利用sort()
function unique(arr) {
    if (!Array.isArray(arr)) {
        console.log('type error!')
        return;
    }
    arr = arr.sort()
    var arrry= [arr[0]];
    for (var i = 1; i < arr.length; i++) {
        if (arr[i] !== arr[i-1]) {
            arrry.push(arr[i]);
        }
    }
    return arrry;
}
     var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
        console.log(unique(arr))
// [0, 1, 15, "NaN", NaN, NaN, {…}, {…}, "a", false, null, true, "true", undefined]      //NaN、{}没有去重
利用sort()排序方法,然后根据排序后的结果进行遍历及相邻元素比对。

2.利用indexOf去重
function unique(arr) {
    if (!Array.isArray(arr)) {
        console.log('type error!')
        return
    }
    var array = [];
    for (var i = 0; i < arr.length; i++) {
        if (array .indexOf(arr[i]) === -1) {
            array .push(arr[i])
        }
    }
    return array;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
   // [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {…}, {…}]  //NaN、{}没有去重
新建一个空的结果数组,for 循环原数组,判断结果数组是否存在当前元素,如果有相同的值则跳过,不相同则push进数组。

3.利用ES6 Set去重
function unique (arr) {
  return Array.from(new Set(arr))
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
 //[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]
不考虑兼容性,这种去重的方法代码最少。这种方法还无法去掉“{}”空对象,后面的高阶方法会添加去掉重复“{}”的方法。

4.利用filter
function unique(arr) {
  return arr.filter(function(item, index, arr) {
    //当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
    return arr.indexOf(item, 0) === index;
  });
}
    var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
        console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {…}, {…}]

21.js去除字符串前后空格

 String.prototype.trim=function(){
      return this.replace(/(^\s*)|(\s*$)/g, "");
   }

22.js语言特性

跨平台性

JavaScript脚本语言不依赖于操作系统,仅需要浏览器的支持。

脚本语言

JavaScript是一种解释型的脚本语言,C、C++等语言先编译后执行,而JavaScript是在程序的运行过程中逐行进行解释。弱类型语言 是相对强类型语言来说的

弱类型语言

在强类型语言中,变量类型有多种,例如int char float boolean 等
不同的类型相互转换有时需要强制转换
而javascript只有一种类型var ,为变量赋值时会自动判断类型并进行转换
所以javascript是弱语言

23.字母全排列 回溯法

import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
public class Solution {
    public ArrayList<String> Permutation(String str) {
        ArrayList<String>resultList = new ArrayList<>();
        if(str.length() == 0)
            return resultList;
        fun(str.toCharArray(),resultList,0);
        Collections.sort(resultList);
        return resultList;
    }
     
    private void fun(char[] ch,List<String> list,int i){
        if(i == ch.length-1){
            if(!list.contains(new String(ch))){
                list.add(new String(ch));
                return;
            }
        }else{
            for(int j=i;j<ch.length;j++){
                swap(ch,i,j);
                fun(ch,list,i+1);
                swap(ch,i,j);
            }
        }
    }
     
    //交换数组的两个下标的元素
    private void swap(char[] str, int i, int j) {
            if (i != j) {
                char t = str[i];
                str[i] = str[j];
                str[j] = t;
            }
        }
    }

24. 事件代理在捕获阶段的实际应用

可以在父元素层面阻止事件向子元素传播,也可代替子元素执行某些操作。

25.有一个游戏叫做Flappy Bird,就是一只小鸟在飞,前面是无尽的沙漠,上下不断有钢管生成,你要躲避钢管。然后小明在玩这个游戏时候老是卡顿甚至崩溃,说出原因(3-5个)以及解决办法(3-5个)

原因可能是:
1.内存溢出问题。
2.资源过大问题。
3.资源加载问题。

解决办法:
1.针对内存溢出问题,我们应该在钢管离开可视区域后,销毁钢管,让垃圾收集器回收钢管,因为不断生成的钢管不及时清理容易导致内存溢出游戏崩溃。
2.针对资源过大问题,我们应该选择图片文件大小更小的图片格式,比如使用webp、png格式的图片,因为绘制图片需要较大计算量。
3.针对资源加载问题,我们应该在可视区域之前就预加载好资源,如果在可视区域生成钢管的话,用户的体验就认为钢管是卡顿后才生成的,不流畅。

26. 编写代码,满足以下条件: (1)Hero("37er");执行结果为 Hi! This is 37er (2)Hero("37er").kill(1).recover(30);执行结果为 Hi! This is 37er Kill 1 bug Recover 30 bloods (3)Hero("37er").sleep(10).kill(2)执行结果为 Hi! This is 37er //等待10s后 Kill 2 bugs //注意为bugs (双斜线后的为提示信息,不需要打印)

function Hero(name)
  {
      var o=new Object();
      o.name=name;
      o.time=0;
      console.log("Hi!This is"+o.name);
      o.kill=function (num) {
          if(num==1)
          {
              console.log("Kill"+num+"bug");
          }else{
              setTimeout(function () {
                  console.log("Kill"+num+"bugs");
              },o.time*1000);
          }
          return o;
      }
      o.recover=function (num1) {
          console.log("Recover"+num1+"bloods");
          return o;
      }
      o.sleep=function (time) {
            o.time=time;
          return o;
      }
      return o;
  }
    Hero("37er");
  Hero("37er").kill(1).recover(30);
  Hero("37er").sleep(10).kill(2);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.几种基本数据类型?复杂数据类型?值类型和引用数据类型?堆栈数据结构? 基本数据类型:Undefined、Nul...
    极乐君阅读 5,603评论 0 106
  • JavaScript 本身可以算是一门简单的语言,但我们也不断用智慧和灵活的模式来改进它。昨天我们将这些模式应用到...
    寒剑飘零阅读 728评论 0 0
  • (原网址:http://blog.csdn.net/stronger_lxs/article/details/51...
    空谷悠阅读 855评论 0 1
  • 优雅降级VS渐进增强 (好像是css3出来之后火起来的,低版本的浏览器针对css3兼容性较差,而又不想放弃优秀的c...
    唯有她美阅读 250评论 0 1
  • 一、数据绑定不一定就是使用双大括号 “{{}}” 语法 我们都知道,Vue.js 最常见的数据绑定方式是使用“Mu...
    前端王睿阅读 1,082评论 4 3