拓展题

作者: 家有饿犬和聋猫 | 来源:发表于2019-08-21 11:13 被阅读0次
    写一个方法,返回10个不重复的正整数

    方式一:

    function num(){
        let  obj= {}
        for(let i=0;i<10;i++){
              let x=Math.round(Math.random()*100);
              // 当数据不存在
              if(obj.x===undefined){
                 obj[x]=x
              }else{
                     // 当数据已存在,重新赋值
                 let newx=Math.round(Math.random()*100)
                  obj[newx]=newx
              }
        }
        
       return  Object.values(obj) 
    }
    
    console.log( num() );
    //[16, 18, 22, 33, 54, 62, 63, 70, 76, 95]
    

    方式二

    function num(){
         
             const list=new Set()
            while(list.size<10){
                list.add(Math.round(Math.random()*100))
            }
        
        //将set对象转化成数组
        return  [...list]
    }
    
    console.log(num())
    //    [70, 40, 33, 61, 84, 20, 44, 21, 34, 51]
    

    Set 对象允许你存储任何类型的唯一值,无论是[原始值]或者是对象引用

    image.png
    给数组随机排序

    简洁版:

    var s=[1,2,3,4,5,6,7] ;
    
     s.sort(()=>Math.random()>0.5?-1:1)  ; 
    
    console.log(s)
    //(7) [2, 1, 4, 6, 5, 3, 7]
    

    常规版:

    h=(arr)=>{
        let len=arr.length
       for(var i=0;i<len-1;i++){
           var index=parseInt(Math.random()*(len-i));   //len-i 的作用是限制index的大小不能超出范围
           var temp=arr[index];            
       arr[index]=arr[len-i-1];          
            arr[len-i-1]=temp;
       }  
    return arr 
    }
    
    var arr=[1,2,3,4,5,6,7,8]
    
    console.log(h(arr))
    
    //(8) [3, 2, 8, 6, 5, 7, 4, 1]
    
    算数乘法表:
      document.write("<table border='1'>");
            for(i=0;i<10;i++){
                 document.write("<tr>")
                    for(j=0;j<10;j++){
                       if(j<=i){
                            document.write("<td>")
                            document.write(`${i}*${j}=${i*j}`)  
                            document.write("</td>")  
                       }else{
    
                       }
                    
                    }
                 document.write("</tr>")
            }
            document.write("</table>");
    
    js中如何检测一个变量是string类型?

    方式一:

    var str='hhhhhhh'
    console.log(str.constructor===String)    
    //  true
    

    方式二:

    Object.prototype.toString.call(str).slice(8,-1)
    //  "String"
    

    方式三:

    typeof str  
    //  "string"
    
    类型比较
       { } == { }  //false         
       [ ] == [ ]  //false
        //在js中,数组和对象属于引用类型数据,==两边是引用类型数据的地址,每当创建一个新的数据时,地址 不同,所以为false
    
    浏览器控制台上会打印什么?
    var a=10 ;
    (()=>{
      console.log(a)
      var a=100
    })()
    // undefined    
    //  原因:  声明  var a 在console.log()之前,赋值 a=100在console.log()之后,所以打印a的时候是undefined; 
    // 解析之后是这样的
      var a=10 ;
    (()=>{
       var a
      console.log(a)
      a=100
    })()
    

    如果把var换成let 或者const ,会输出10

    "newarr"中有哪些元素?
    var arr=[]  
    for(i=0;i<3;i++){
      arr.push(()=>i)
    }
    var newarr = arr.map(
     el=>el()
    )
    console.log(newarr)
    //  (3) [3, 3, 3]
    

    解析: arr: [ ()=>i, ()=>i, ()=>i ]
    for循环头部 用var定义变量i,会为该变量创建单向的存储空间,三个箭头函数体中的每个'i'都指向相同的绑定,循环结束之后i为3
    如果使用 let 声明一个具有块级作用域的变量,则为每个循环迭代创建一个新的绑定
    每个'i'指的是一个新的的绑定,并保留当前的值,因此每个箭头函数返回一个不同的值。

    // 使用ES6块级作用域
    var array = [];
    for (let i = 0; i < 3; i++) {
      // 这一次,每个'i'指的是一个新的的绑定,并保留当前的值。
     // 因此,每个箭头函数返回一个不同的值。
      array.push(() => i);
    }
    var newArray = array.map(el => el());
    console.log(newArray); // [0, 1, 2]
    
    
    解决这个问题的另一种方法是使用[闭包](http://dmitrysoshnikov.com/ecmascript/chapter-6-closures/)。
    let array = [];
    for (var i = 0; i < 3; i++) {
      array[i] = (function(x) {
        return function() {
          return x;
        };
      })(i);
    }
    const newArray = array.map(el => el());
    console.log(newArray); // [0, 1, 2]  
    
    如果我们在浏览器控制台中运行'foo'函数,是否会导致堆栈溢出错误?
    function foo() {
      setTimeout(foo, 0); // 是否存在堆栈溢出错误?
    }; 
    
    

    解析:

    JavaScript并发模型基于“事件循环”。 当我们说“浏览器是 JS 的家”时我真正的意思是浏览器提供运行时环境来执行我们的JS代码。

    浏览器的主要组件包括调用堆栈事件循环****,任务队列Web API。 像setTimeoutsetIntervalPromise这样的全局函数不是JavaScript的一部分,而是 Web API 的一部分。 JavaScript 环境的可视化形式如下所示:

    [图片上传失败...(image-78bfc4-1566531357288)]

    JS调用栈是后进先出(LIFO)的。引擎每次从堆栈中取出一个函数,然后从上到下依次运行代码。每当它遇到一些异步代码,如setTimeout,它就把它交给Web API(箭头1)。因此,每当事件被触发时,callback 都会被发送到任务队列(箭头2)。

    image.png

    事件循环(Event loop)不断地监视任务队列(Task Queue),并按它们排队的顺序一次处理一个回调。每当调用堆栈(call stack)为空时,Event loop获取回调并将其放入堆栈(stack )(箭头3)中进行处理。请记住,如果调用堆栈不是空的,则事件循环不会将任何回调推入堆栈

    现在,有了这些知识,让我们来回答前面提到的问题:

    步骤

    1. 调用 foo()会将foo函数放入调用堆栈(call stack)
    2. 在处理内部代码时,JS引擎遇到setTimeout
    3. 然后将foo回调函数传递给WebAPIs(箭头1)并从函数返回,调用堆栈再次为空
    4. 计时器被设置为0,因此foo将被发送到任务队列<Task Queue>(箭头2)。
    5. 由于调用堆栈是空的,事件循环将选择foo回调并将其推入调用堆栈进行处理。
    6. 进程再次重复,堆栈不会溢出。
    在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2
    //输出所有数字都在0到n-1的范围内的数字
    fit=(n)=>{
      let num=Math.round(Math.random()*10)
       if(num<n){
          return num
       }else{
          //这里需要加return  否则输出undefined
          return  fit(n);
       }
    }
    
    
    fn=(n)=>{
       let arr=[];
       while(arr.length<n){
         arr.push(fit(n))
       }
     //生成数组arr
       let objs={}
      console.log("arr",arr)
    arr.map(p=>{
         
         if(objs[p]===undefined){
            objs[p]=1
         }else{
           objs[p]=1+ objs[p]
         }
    })
       // objs储藏每个数字出现的次数
    return  objs
    }
    fn(7);
    // arr (7) [5, 4, 1, 4, 5, 6, 1]
    //  {1: 2, 4: 2, 5: 2, 6: 1}
    
    //简洁版: 输出所有数字都在0到n-1的范围内的数字
    
    Math.floor(Math.random() * n)   
    可以代替fit()函数的功能
    
    

    相关文章

      网友评论

          本文标题:拓展题

          本文链接:https://www.haomeiwen.com/subject/jdlbsctx.html