• 前端面试题及答案,JS方面的


    1.1、请解释一下什么是闭包

    当函数可以记住并访问所在的作用域时,就产生了闭包,即使函数是在当前作用域之外执行。闭包有如下特性:

    a. JavaScript允许你使用在当前函数以外定义的变量

    b. 即使外部函数已经返回,当前函数仍然可以引用在外部函数所定义的变量

    c. 闭包可以更新外部变量的值

    d. 用闭包模拟私有方法

    由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题。

    在定时器、事件监听器、Ajax请求、跨窗口通信、Web Workers或者任何其他的异步(或者同步)任务中,只要使用了回调函数,实际上就是在使用闭包! 

    1.2call apply 的区别是什么?

    call 和 apply 就是为了改变函数体内部 this 的指向。

    区别是从第二个参数起,call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。

    当参数明确时用call与apply都行, 当参数不明确时可用apply给合arguments

     

    1.3、如何使用原生 Javascript 代码深度克隆一个对象(注意区分对象类型)

    用递归的方式克隆

    function deepClone(obj)
    
    {
    
      var o,i,j,k;
    
      if(typeof(obj)!="object" || obj===null)return obj;
    
      if(obj instanceof(Array))
    
      {
    
        o=[];
    
        i=0;j=obj.length;
    
        for(;i<j;i++)
    
        {
    
          if(typeof(obj[i])=="object" && obj[i]!=null)
    
          {
    
            o[i]=arguments.callee(obj[i]);
    
          }
    
          else
    
          {
    
            o[i]=obj[i];
    
          }
    
        }
    
      }
    
      else
    
      {
    
        o={};
    
        for(i in obj)
    
        {
    
          if(typeof(obj[i])=="object" && obj[i]!=null)
    
          {
    
            o[i]=arguments.callee(obj[i]);
    
          }
    
          else
    
          {
    
            o[i]=obj[i];
    
          }
    
        }
    
      }
    
      return o;
    
    }
    
    var scheduleClone = deepClone(schedule)
    
    scheduleClone.data[0].contactList.phone[0] = 99999999999
    
    console.log('方法1 深度克隆')
    
    console.log(scheduleClone)
    
    console.log(JSON.stringify(schedule))
    
    console.log(JSON.stringify(scheduleClone))

    用js原生的json序列化的方式

    var scheduleClone2 = JSON.parse(JSON.stringify(schedule));
    
    console.log(scheduleClone2)
    
    scheduleClone2.data[0].contactList.phone[0] = 8888888
    
    console.log(JSON.stringify(schedule))
    
    console.log(JSON.stringify(scheduleClone2))

    1.4 jQuery $(′.class′)$('div.class') 哪个效率更高?

    jQuery内部使用Sizzle引擎,处理各种选择器。Sizzle引擎的选择顺序是从右到左,所以这条语句是先选.class,

    第二个会直接过滤出div标签,而第一个就不会过滤了,将所有相关标签都列出。

     

    1.5、实现输出document对象中所有成员的名称和类型

    for(o in document){
    
               type = Object.prototype.toString.call(document[o]);
    
               if(type =='[object Function]'){
    
                     console.log(o+":"+typeof o)
    
               }
    
    }  

    1.6、获得一个DOM元素的绝对位置

    offsetTop:返回当前元素相对于其 offsetParent 元素的顶部的距离

    offsetLeft:返回当前元素相对于其 offsetParent 元素的左边的距离

    getBoundingClientRect():返回值是一个DOMRect对象,它包含了一组用于描述边框的只读属性——left、top、right和bottom,属性单位为像素

    1.7、如何利用JS生成一个table

    首先是用createElement创建一个table,再用setAttribute设置table的属性,

    然后用for循环设置tr和td的内容,用appendChild拼接内容,设置td的时候还用到innerHTMLstyle.padding。

    var row, cell,
    
         table = document.createElement("table");
    
         table.setAttribute("border", 1);
    
         for (var i = 0; i < 10; i++) {
    
             row = document.createElement("tr");
    
             table.appendChild(row);
    
             for (var j = 0; j < 10; j++) {
    
                 cell = document.createElement("td");
    
                 cell.style.padding = "10px";
    
                 cell.innerHTML = "单元格内容";
    
                 row.appendChild(cell);
    
             }
    
         };
    
         table.appendChild(row);
    
         document.body.appendChild(table); 

    1.8、实现预加载一张图片,加载完成后显示在网页中并设定其高度为50px,宽度为50px

       

       var img = new Image();
    
          img.src = "1.jpg";
    
          img.onload = function() {
    
            img.height = 50;
    
            img.width = 50;
    
          }
    
          document.body.appendChild(img);

    1.9、假设有一个4trtable,将table里面tr顺序颠倒

    先是通过table.tBodies[0].rows获取到当前tbody中的行,接下来是两种方法处理。获取到的行没有reverse这个方法。

    1.第一种是将这些行push到另外一个数组中

    var tableTemple=document.querySelector("#tableTemple");
    
    var table_rows=tableTemple.tBodies[0].rows;
    
    var newAry=[];
    
         for(var i=0;i<table_rows.length;i++){
    
               newAry.unshift(table_rows[i]);
    
         };
    
         for(i in newAry){
    
               tableTemple.tBodies[0].appendChild(newAry[i]);
    
         }

    2.第二种是用Array.prototype.slice.call()将那些行变成数组,接着用reverse倒叙,table再appendChild。

     var tableTemple=document.querySelector("#tableTemple");
    
    var table_rows=tableTemple.tBodies[0].rows;
    
    var trs = Array.prototype.slice.call(table_rows, 0);Array.prototype.slice.call(arguments)//能将具有length属性的对象转成数组
    
        trs.reverse();
    
         for(var i=0;i<trs.length;i++){
    
               tableTemple.tBodies[0].appendChild(trs[i]);
    
         }

    1.10、模拟一个HashTable类,一个类上注册四个方法:包含有addremovecontainslength方法

    先是在构造函数中定义一个数组,然后用push模拟add,splice模拟remove。

    四个方法都放在了prototype上面。

    function HashTable(){
    
               this.value=[];
    
         };
    
         HashTable.prototype.add=function(val){
    
               this.value.push(val);
    
         };
    
         HashTable.prototype.remove=function(index){
    
               this.value.splice(index,1)
    
         }
    
         HashTable.prototype.contains=function(val){
    
               var aValue=this.value;
    
               for(i in aValue){
    
                    if(val==aValue[i]){
    
                          return true;
    
                    }
    
               }
    
               return false;
    
         }
    
         HashTable.prototype.length = function() {
    
             return this.value.length;
    
         }

     

    1.11Ajax读取一个XML文档并进行解析的实例

    a. 初始化一个HTTP请求,IE以ActiveX对象引入。 后来标准浏览器提供了XMLHttpRequest类,它支持ActiveX对象所提供的方法和属性

    b. 发送请求,可以调用HTTP请求类的open()和send()方法

    c. 处理服务器的响应,通过http_request.onreadystatechange = nameOfTheFunction。来指定函数

    //创建请求对象
    
    function create() {
    
      if (window.XMLHttpRequest) { // Mozilla, Safari, ...
    
          http_request = new XMLHttpRequest();
    
      } else if (window.ActiveXObject) { // IE
    
          http_request = new ActiveXObject("Microsoft.XMLHTTP");
    
      }
    
      return http_request;
    
    }
    
    //发起请求
    
    function makeRequest(url) {
    
      http_request = create();
    
      http_request.onreadystatechange = alertContents;
    
      http_request.open('GET', url, true);
    
      http_request.send(null);
    
    }
    
    //响应函数
    
    function alertContents() {
    
       if (http_request.readyState == 4) {
    
          if (http_request.status == 200) {
    
              var xmldoc = http_request.responseXML;
    
              var root_node = xmldoc.getElementsByTagName('root').item(0);
    
              alert(root_node.firstChild.data);
    
          } else {
    
             alert('There was a problem with the request.');
    
          }
    
       }
    
    } 

    1.12JS如何实现面向对象和继承机制?

    创建对象方法:

    a. 利用json创建对象

    b. 使用JavaScript中的Object类型

    c. 通过创建函数来生成对象

    继承机制:

    a. 构造函数绑定,使用call或apply方法,将父对象的构造函数绑定在子对象上

    b. prototype模式,继承new函数的模式

    c. 直接继承函数的prototype属性,对b的一种改进

    d. 利用空对象作为中介

    e. 在ECMAScript5中定义了一个新方法Object.create(),用于创建一个新方法

    f. 拷贝继承,把父对象的所有属性和方法,拷贝进子对象,实现继承。

     

    1.13JS模块的封装方法,比如怎样实现私有变量,不能直接赋值,只能通过公有方法

    a. 通过json生成对象的原始模式,多写几个就会非常麻烦,也不能反映出它们是同一个原型对象的实例

    b. 原始模式的改进,可以写一个函数,解决代码重复的问题。同样不能反映出它们是同一个原型对象的实例

    c. 构造函数模式,就是一个普通函数,不过内部使用了this变量,但是存在一个浪费内存的问题。

    d. Prototype模式,每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承,可以把那些不变的属性和方法,直接定义在prototype对象上。Prototype模式的验证方法:isPrototypeOf()hasOwnProperty()in运算符。

    //通过json生成对象的原始模式
    
    var cat1 = {}; // 创建一个空对象
    
    cat1.name = "大毛"; // 按照原型对象的属性赋值
    
    cat1.color = "黄色";
    
    var cat2 = {};
    
    cat2.name = "二毛";
    
    cat2.color = "黑色";
    
     
    
    //原始模式的改进
    
    function Cat2(name,color){
    
      return {
    
        name:name,
    
        color:color
    
      }
    
    }
    
     
    
    //构造函数模式
    
    function Cat3(name,color){
    
      this.name=name;
    
      this.color=color;
    
    }
    
     
    
    //Prototype模式
    
    function Cat4(name,color){
    
      this.name = name;
    
      this.color = color;
    
    }
    
    Cat4.prototype.type = "猫科动物";
    
    Cat4.prototype.eat = function(){alert("吃老鼠")};
    
     
    
    //Prototype验证方法
    
    var human = function() {}
    
    var socrates = Object.create(human);
    
    console.log(human.isPrototypeOf(socrates)); //=> true
    
    //console.log(socrates.prototype.isPrototypeOf(human));
    
    console.log(socrates instanceof human); //=> false
    
    //console.log(socrates.prototype) 

    1.14、对this指针的理解,可以列举几种使用情况?

    this实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。

    this指的是:调用函数的那个对象。

    a. 纯粹的函数调用,属于全局性调用,因此this就代表全局对象Global。

    b. 作为对象方法的调用,这时this就指这个上级对象。

    c. 作为构造函数调用,就是通过这个函数new一个新对象(object)。这时,this就指这个新对象。

    d. applycall的调用,它们的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象。

    //a. 纯粹的函数调用
    
    function test1() {
    
      this.x = 1;
    
      console.log(this.x);
    
    }
    
    test1(); // 1
    
     
    
    var y = 1;
    
     
    
    function test2() {
    
      console.log(this.y);
    
    }
    
    test2(); // 1
    
     
    
    var z = 1;
    
     
    
    function test3() {
    
      this.z = 2;
    
    }
    
    test3();
    
    console.log(z); //2
    
     
    
    //b. 作为对象方法的调用
    
    function test4() {
    
      console.log(this.x);
    
    }
    
    var o = {};
    
    o.x = 10;
    
    o.m = test4;
    
    o.m(); // 10
    
     
    
    //c.作为构造函数调用
    
    function test5() {
    
      this.x = 1;
    
    }
    
    var o = new test5();
    
    console.log(o.x); // 1
    
     
    
    //d.apply与call的调用
    
    var x = 0;
    
     
    
    function test6() {    
    
      console.log(this.x);  
    
    }  
    
    var o = {};  
    
    o.x = 1;  
    
    o.m = test6;  
    
    o.m.apply(o); //1 

    1.15、在JavaScript中,常用的绑定事件的方法有哪些?

    a. 在DOM元素中直接绑定,DOM元素,可以理解为HTML标签,onXXX="JavaScript Code"。

    b. 在JavaScript代码中绑定,elementObject.onXXX=function(){},通称为DOM0事件系统。

    c. 绑定事件监听函数,标准浏览器使用 addEventListener() ,IE11以下版本attachEvent() 来绑定事件监听函数,通称为DOM2事件系统。

    1.16、解释下javascript的冒泡和捕获

    <div id="click1">

      <div id="click2">

         <div id="click3">事件</div>

      </div>

    </div>

    a. Netscape主张元素1的事件首先发生,这种事件发生顺序被称为捕获型

    b. 微软则保持元素3具有优先权,这种事件顺序被称为冒泡型

    c. W3C选择了一个择中的方案。任何发生在w3c事件模型中的事件,首是进入捕获阶段,直到达到目标元素,再进入冒泡阶段

    事件监听函数addEventListener()的第三个参数就是控制方法是捕获还是冒泡

        click1 = document.getElementById("click1");
    
         click2 = document.getElementById("click2");
    
         click3 = document.getElementById("click3");
    
         click1.addEventListener("click", returnTarget, false);
    
         click2.addEventListener("click", returnTarget, false);
    
         click3.addEventListener("click", returnTarget, false);
    
         function returnTarget(event) {
    
           console.log(event.currentTarget.id);
    
           //event.stopPropagation();
    
         }

    1.17jQuery的特点

    a. 一款轻量级的js库

    b. 丰富快速的DOM选择器

    c. 链式表达式

    d. 事件、样式、动画等特效支持

    e. Ajax操作封装,支持跨域

    f. 跨浏览器兼容

    g. 插件扩展开发

     

    1.18Ajax有哪些好处和弊端?

    优点:

    a. 无刷新更新数据

    b. 异步与服务器通信

    c. 前端和后端负载平衡

    d. 基于标准被广泛支持

    e. 界面与应用分离

    缺点:

    a. AJAX干掉了Back和History功能,即对浏览器机制的破坏

    b. AJAX的安全问题

    c. 对搜索引擎支持较弱

    d. 违背URL和资源定位的初衷

    参考《AJAX工作原理及其优缺点

     

    1.19nullundefined的区别?

    null

    a. null是一个表示"无"的对象,转为数值时为0

    b. null表示"没有对象",即该处不应该有值。

    undefined

    a. undefined是一个表示"无"的原始值,转为数值时为NaN。

    b. undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。

     

    1.20new操作符具体干了什么呢?

    a. 一个新对象被创建。它继承自函数原型

    b. 构造函数被执行。执行的时候,相应的传参会被传入

    c. 上下文(this)会被指定为这个新实例

    d. 如果构造函数返回了一个“对象”,那么这个对象会取代整个new出来的结果

     

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

    a. 将script节点放置在最后</body>之前

    b. 使用script标签的defer和async属性,defer属性为延迟加载,是在页面渲染完成之后再进行加载的,而async属性则是和文档并行加载

    c. 通过监听onload事件,动态添加script节点

    d. 通过ajax下载js脚本,动态添加script节点

    1.22、如何解决跨域问题?

    a. JSONP(JSON with Padding),填充式JSON

    b. iframe跨域

    c. HTML5的window.postMessage方法跨域

    d. 通过设置img的src属性,进行跨域请求

    e. 跨域资源共享(CORS),服务器设置Access-Control-Allow-OriginHTTP响应头之后,浏览器将会允许跨域请求

     

    1.23documen.write innerHTML的区别

    write

    a. 改变 HTML 输出流

    b. 当在文档加载之后使用 document.write(),这会覆盖该文档。例如onload事件中

    c. 输入css的style标签能改变样式,例如document.write("<style>b{color:red;font-weight:bold;}</style>");

    innerHTML

    a. 改变 HTML 内容

    b. 输入cssstyle标签不能改变样式。也是能改变样式的

     

    1.24、哪些操作会造成内存泄漏?

    a. 当页面中元素被移除或替换时,若元素绑定的事件仍没被移除,在IE中不会作出恰当处理,此时要先手工移除事件,不然会存在内存泄露。

    b. 在IE中,如果循环引用中的任何对象是 DOM 节点或者 ActiveX 对象,垃圾收集系统则不会处理。

    c. 闭包可以维持函数内局部变量,使其得不到释放。

    d. 在销毁对象的时候,要遍历属性中属性,依次删除,否则会泄漏。

     

    1.25JavaScript中的变量声明提升?

    函数声明和变量声明总是被JavaScript解释器隐式地提升到包含他们的作用域的最顶端。

    function优先声明于var。

    函数表达式中只会提升名称,函数体只有在执行到赋值语句时才会被赋值。

    function foo() {

        bar();

        var x = 1;

    }

    function foo() {//等同于

        var x;

        bar();

        x = 1;

    }

    function test() {

        foo(); // TypeError "foo is not a function"

        bar(); // "this will run!"

        var foo = function () { }// 函数表达式被赋值给变量'foo'

        function bar() { }// 名为'bar'的函数声明

    }

     

    1.26、如何判断当前脚本运行在浏览器还是node环境中?

    通过判断Global对象是否为window,如果是window,当前脚本运行在浏览器中

     

    1.27、什么是 "use strict"

    ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode)

    设立"严格模式"的目的,主要有以下几个:

    a. 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;

    b. 消除代码运行的一些不安全之处,保证代码运行的安全;

    c. 提高编译器效率,增加运行速度;

    d. 为未来新版本的Javascript做好铺垫。

    注:经过测试IE6,7,8,9均不支持严格模式

     

    1.28eval是做什么的?

    eval()函数可计算某个字符串,并执行其中的的 JavaScript 代码。

    eval()是一个顶级函数并且跟任何对象无关。

    如果字符串表示了一个表达式,eval()会对表达式求值。如果参数表示了一个或多个JavaScript声明, 那么eval()会执行声明。

     

    1.29JavaScript原型,原型链

    原型:

    a. 原型是一个对象,其他对象可以通过它实现属性继承。

    b. 一个对象的真正原型是被对象内部的[[Prototype]]属性(property)所持有。浏览器支持非标准的访问器__proto__。

    c. 在javascript中,一个对象就是任何无序键值对的集合,如果它不是一个主数据类型(undefined,null,boolean,number,string),那它就是一个对象。

    原型链:

    a. 因为每个对象和原型都有一个原型(注:原型也是一个对象),对象的原型指向对象的父,而父的原型又指向父的父,我们把这种通过原型层层连接起来的关系称为原型链。

    b. 这条链的末端一般总是默认的对象原型。

    a.__proto__ = b;

    b.__proto__ = c;

    c.__proto__ = {}; //default object

    {}.__proto__.__proto__; //null

     

     

    1.30JQueryjQuery UI 有啥区别?

    jQuery是一个js库,主要提供的功能是选择器,属性修改和事件绑定等等。

    jQuery UI则是在jQuery的基础上,利用jQuery的扩展性,设计的插件。提供了一些常用的界面元素,诸如对话框、拖动行为、改变大小行为等等

     

    1.31jQuery的源码看过吗?能不能简单说一下它的实现原理?

    jQuery给我们带来了一个简洁方便的编码模型(1>创建jQuery对象;2>直接使用jQuery对象的属性/方法/事件),

    一个强悍的dom元素查找器($),插件式编程接口(jQuery.fn),以及插件初始化的”配置”对象思想

     

    1.32jQuery 中如何将数组转化为json字符串

    在jQuery1.8.3中有个方法“parseJSON”,在这个方法中会做从string转换为json。

    如果当前浏览器支持window.JSON,那就直接调用这个对象中的方法。

    如果没有就使用( new Function( "return " + data ) )();执行代码返回。

    1.33、请写出console.log中的内容

      var msg = 'hello';//顶级作用域window下有个变量msg

      function great(name, attr) {

         var name = 'david';

          var greating = msg + name + '!';

          var msg = '你好';

          for (var i = 0; i < 10; i++) {

              var next = msg + '你的id是' + i * 2 + i;

          }

    console.log(arguments[0]);// david

    console.log(arguments[1]);// undefined

    console.log(greating);// undefineddavid!

    console.log(next);// 你好你的id是189

     }

    great('Tom')

     

    1.35、请说明下下面代码的执行过程

     var t=true;

     window.setTimeout(function(){

             t=false;

     },1000);

     while(t){

       console.log(1);

     }

     alert('end');

    a. JavaScript引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序

    b. setTimeout是异步线程,需要等待js引擎处理完同步代码(while语句)之后才会执行,while语句直接是个死循环,js引擎没有空闲,不会执行下面的alert,也不会插入setTimeout。我在chrome中执行在线代码,最后浏览器是终止死循环执行alert。

    c. JavaScript的工作机制是:当线程中没有执行任何同步代码的前提下才会执行异步代码,setTimeout是异步代码,所以setTimeout只能等js空闲才会执行,但死循环是永远不会空闲的,所以setTimeout也永远不会执行。

     

    1.36、输出今天的日期,以YYYY-MM-DD的方式,比如今天是2014926日,则输出2014-09-26

    function getCurrentDate(){

           var timeStr = '-';

           var curDate = new Date();

           var curYear =curDate.getFullYear();  //获取完整的年份(4位,1970-????)

           var curMonth = curDate.getMonth()+1;  //获取当前月份(0-11,0代表1月)

           var curDay = curDate.getDate();       //获取当前日(1-31)

           var curWeekDay = curDate.getDay();    //获取当前星期X(0-6,0代表星期天)

           var curHour = curDate.getHours();      //获取当前小时数(0-23)

           var curMinute = curDate.getMinutes();   // 获取当前分钟数(0-59)

           var curSec =curDate.getSeconds();      //获取当前秒数(0-59)

           var Current= curYear+timeStr+curMonth+timeStr+curDay+' '+curHour+':'+curMinute+':'+curSec;

              console.log(Current);

              return Current;

           }

         getCurrentDate()

    1.37Javascriptcalleecaller的作用?

    arguments.callee属性包含当前正在执行的函数。

    Function.caller返回一个对函数的引用,该函数调用了当前函数。

     

     

    1.39JS异步编程方式有几种?

    a. 回调函数

    b. 事件监听

    c. 发布订阅

    d. promise

     

    1.40、请说说在JavaScript引用类型和值类型的理解

    值类型:存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。即Undefined、Null、Boolean、Number 和 String。

    引用类型:存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。即对象、数组

    var a = {n:1};

    var b = a; 

    a.x = a = {n:2};

    console.log(a.x);// --> undefined

    console.log(b.x);// --> [object Object]

     

    1.41、请解释一下JavaScript中的作用域和作用域链

    变量的作用域(scope):程序源代码中定义这个变量的区域。

    作用域链:是一个对象列表或链表,这组对象定义了这段代码“作用域中”的变量。查找变量会从第一个对象开始查找,有则用,无则查找链上的下一个对象。

    1.42、用例子来讲事件委托过程

    <input type="button" name="" id="btn" value="添加" />
        <ul id="ul1">
            <li>111</li>
            <li>222</li>
            <li>333</li>
            <li>444</li>
    </ul>
    
    window.onload = function(){
                    var oBtn = document.getElementById("btn");
                    var oUl = document.getElementById("ul1");
                    var aLi = oUl.getElementsByTagName('li');
                    var num = 4;
                    
                    //事件委托,添加的子元素也有事件
                    oUl.onmouseover = function(ev){
                        var ev = ev || window.event;
                        var target = ev.target || ev.srcElement;
                        if(target.nodeName.toLowerCase() == 'li'){
                            target.style.background = "red";
                        }
                        
                    };
                    oUl.onmouseout = function(ev){
                        var ev = ev || window.event;
                        var target = ev.target || ev.srcElement;
                        if(target.nodeName.toLowerCase() == 'li'){
                            target.style.background = "#fff";
                        }
                        
                    };
                    
                    //添加新节点
                    oBtn.onclick = function(){
                        num++;
                        var oLi = document.createElement('li');
                        oLi.innerHTML = 111*num;
                        oUl.appendChild(oLi);
                    };
                }

     1.43、数组去重

    方法1:ES6 Set函数

    var strAry=[1, 2, 3, 4, 4];
    var set = new Set(strAry);
    console.log(set)//[1,2,3,4]

    方法2:利用对象属性存在的特性,如果没有该属性则存入新数组。

    var strAry=[1, 2, 3, 4, 4];
    function unique(arr) {
    var obj={}
                var newArr=[]
                for (let i = 0; i < arr.length; i++) {
                    if (!obj[arr[i]]) {
                        obj[arr[i]] = 1
                        newArr.push(arr[i])
                    }   
                }
                return newArr
            }
    console.log(unique(strAry))
     

     方法2:利用数组的indexOf下标属性来查询。

    
    
    var strAry=[1, 2, 3, 4, 4];
    function unique4(arr) {
                var newArr = []
                for (var i = 0; i < arr.length; i++) {
                    if (newArr.indexOf(arr[i])===-1) {
                        newArr.push(arr[i])
                    }
                }
                return newArr
     }
     console.log(unique4(strAry))

      1.44、跨域解决方案

    1、 通过jsonp跨域
    2、 document.domain + iframe跨域
    3、 location.hash + iframe
    4、 window.name + iframe跨域
    5、 postMessage跨域
    6、 跨域资源共享(CORS)
    7、 nginx代理跨域
    8、 nodejs中间件代理跨域
    9、 WebSocket协议跨域

      

  • 相关阅读:
    c#pc上测试微信端企业公众商城个人中心链接的工具JMeter
    eclipse java tomcat 远程调试
    Java多线程-线程池ThreadPoolExecutor构造方法和规则
    servlet3异步原理与实践
    eclipse Filter web.xml 问题解决 异步请求@WebServlet
    c# maiform父窗体改变动态的gridew 奇偶行变色的快捷方法
    java redispool测试类保存
    c#dev gridview 设置隔行换色等
    c#devexpress 窗体控件dock的重要
    devexpress总结 accordionControl 加载panelcontrol 的快捷方式
  • 原文地址:https://www.cnblogs.com/binmengxue/p/12120054.html
Copyright © 2020-2023  润新知