Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第 101 题:修改以下 print 函数,使之输出 0 到 99,或者 99 到 0 #158

Open
yygmind opened this issue Jul 8, 2019 · 86 comments

Comments

@yygmind
Copy link
Contributor

yygmind commented Jul 8, 2019

要求:

1、只能修改 setTimeoutMath.floor(Math.random() * 1000 的代码

2、不能修改 Math.floor(Math.random() * 1000

3、不能使用全局变量

function print(n){
  setTimeout(() => {
    console.log(n);
  }, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}
@yygmind yygmind added the 字节 label Jul 8, 2019
@momodiy
Copy link

momodiy commented Jul 8, 2019

function print(n){
  setTimeout((() => {
    console.log(n)
    return ()=>{}
  }).call(n,[]), Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

@Gentlemancj
Copy link

function print(n){ setTimeout(() => { console.log(n); }, Math.floor(Math.random()+1) * 1000); } for(var i = 0; i < 100; i++){ print(i); }

@ryanZiegler
Copy link

ryanZiegler commented Jul 9, 2019

function print(n){
  setTimeout(() => {
    console.log(n);
  }, 1, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

@hzxfjmc
Copy link

hzxfjmc commented Jul 9, 2019

function print(n){
setTimeout((() => {
console.log(n);
}).apply(n), Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
print(i);
}

@dorseysen
Copy link

dorseysen commented Jul 9, 2019

第一种解法:

function print(n) {

    setTimeout( (() => {

        console.log(n);
    
    })(), Math.floor(Math.random() * 1000));
}


for(var i = 0; i < 100; i++){
    print(i);
}

另一种解法则是根据setTimeout的时间戳,只要让它按照时间戳顺序打印即可。但这样的时间耗时相当长。

function print(n){

    setTimeout(() => {
        
        setTimeout( () =>{
            console.log(n);
        }, 1000 * n);

    }, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
    print(i);
}

@ramey502
Copy link

ramey502 commented Jul 9, 2019

楼上匿名函数自执行是一种解法,直接利用表达式也是一种解法!

function print(n){
  setTimeout(console.log(n), Math.floor(Math.random() * 1000));
}

for(var i = 0; i < 100; i++) {
  print(i);
}

99到0,就是 99 - n

function print(n){
  setTimeout(console.log(99 - n), Math.floor(Math.random() * 1000));
}

for(var i = 0; i < 100; i++) {
  print(i);
}

@defypro
Copy link

defypro commented Jul 9, 2019

综合上面各位大佬的答案,使用立即执行函数如果没有return值的话相当于

setTimeout(undefined, Math.floor(Math.random() * 1000));

浏览器会报错,所以还是需要加入返回值的

 setTimeout( (() => {
        console.log(n);
    	return ()=>{};
  })(), Math.floor(Math.random() * 1000));

@luohong123
Copy link

  1. 依次打印出 0-99
function print(n){
  setTimeout(() => {
    setTimeout(()=>{
       console.log(n);
    },1000*n)
  }, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}
  1. 依次打印出99-0
function print(n){
  setTimeout(() => {
    setTimeout(()=>{
       console.log(99-n);
    },1000*n)
  }, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

@white-dew
Copy link

function print(n){
  print.n === undefined ? (print.n = 0) : (n !== 0 && print.n + 1 !== n) ? (setTimeout(() => {print(n)}, 1000)) : (setTimeout(() => {
    console.log(n);
    print.n += 1
  }, Math.floor(Math.random() * 1000)))
}
for(var i = 0; i < 100; i++){
  print(i);
}

@wwervin72
Copy link

综合上面大佬给出的答案,感觉这题就是打乱了输出顺序,根本解决办法无外乎就是让定时器里的函数在同一任务队列里去执行,立即执行函数可以实现,或者给任意只要相同的时间间隔也可以实现。

@rongda
Copy link

rongda commented Jul 9, 2019

1、闭包,匿名函数自执行 ,即使创建它的上下文已经销毁,变量仍然存在,
2、是随机输出 0 到 99,或者 99 到 0?

@liuzeyang
Copy link

两种解法:

  1. 利用settimeout 接受多个参数的方向,将Math.floor(Math.random() * 1000)作为第三个参数,第二参数可以设置为任意值。
    function print(n){
    setTimeout(() => {
    console.log(n);
    }, 1, Math.floor(Math.random() * 1000));
    }
    for(var i = 0; i < 100; i++){
    print(i);
    }
    2.可以利用settimeout 第一个参数可以是function是立即执行或者一个执行函数。

@wineSu
Copy link

wineSu commented Jul 9, 2019

综合上面各位大佬的答案,使用立即执行函数如果没有return值的话相当于

setTimeout(undefined, Math.floor(Math.random() * 1000));

浏览器会报错,所以还是需要加入返回值的

 setTimeout( (() => {
        console.log(n);
    	return ()=>{};
  })(), Math.floor(Math.random() * 1000));

没有报错啊

@MoveZZG
Copy link

MoveZZG commented Jul 9, 2019

忽略Math.floor(Math.random() * 1000) 影响(不过打印的太慢了吧(#`O′))

function print(n){
setTimeout(() => {
setTimeout(()=>{
console.log(n);
},(n+1)*1000);
}, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
print(i);
}

@nano-papa
Copy link

nano-papa commented Jul 9, 2019

综合上面各位大佬的答案,使用立即执行函数如果没有return值的话相当于

setTimeout(undefined, Math.floor(Math.random() * 1000));

浏览器会报错,所以还是需要加入返回值的

 setTimeout( (() => {
        console.log(n);
    	return ()=>{};
  })(), Math.floor(Math.random() * 1000));
window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. >*/) {
var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
return __nativeST__(vCallback instanceof Function ? function () {
vCallback.apply(oThis, aArgs);
} : vCallback, nDelay);
};`

只是判断是不是function类型

@Weathers0086
Copy link

function print(n){
setTimeout( (() => {
console.log(n);
return ()=>{};
})(), Math.floor(Math.random() * 1000));
}
for(var i=0;i<100;i++){
print(i)
}

@kungithub
Copy link

kungithub commented Jul 9, 2019

// 方法1 利用for的变量i  输出99-0
function print(n){
  setTimeout(() => {
    console.log(--i);
  }, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

//方法2 将setTimeout 的时间改为 0*Math.floor(Math.random() * 1000) .. 取巧了一下
// 输出0-99
function print(n){
  setTimeout(() => {
    console.log(n);
  }, 0*Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

@824759494
Copy link

824759494 commented Jul 9, 2019

  1. 0-99
function print(n){
  setTimeout(() => {
    console.log(n);
  }, 1, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}
  1. 99-0
function print(n){
  setTimeout(() => {
    console.log(99 - n);
  }, 1, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

@supermanklk
Copy link

function print(n){
setTimeout(() => {
console.log((i++)-100);
}, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
print(i);
}

@FEJiuL
Copy link

FEJiuL commented Jul 9, 2019

function print(n){
  setTimeout((n) => {
    console.log(n);
  },0,n, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

把Math.random挤掉就好了。

@5SSS
Copy link

5SSS commented Jul 9, 2019

0 -99
function print(n){
  setTimeout((function () {
	console.log(n)
	return function () {}
  })(), Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

99 - 0
function print(n){
  setTimeout((function () {
	console.log(Math.abs(n - 99))
	return function () {}
  })(), Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

@song-le-yi
Copy link

emm,楼主不给答案讲解得嘛

@supermanklk
Copy link

emm,楼主不给答案讲解得嘛

我理解的讲一下,2种方法
1.立即执行函数
2.定时器第二位重新赋固定的值

@james9527
Copy link

james9527 commented Jul 9, 2019

题目解析:向setTimeout() 传递一个函数时,该函数中的this指向跟你的期望可能不同,当前这些代码中包含的 this 关键字在非严格模式会指向window对象,严格模式下为undefined。此时可以借助call或apply去改变this指向,即可顺序打印出0到99(或倒序99到0)

function print(n){
  setTimeout((() => {
    // console.log(this.i); // 如果不借助call会打印出100次全局变量i,值都为100
    console.log(n); // 顺序打印出0~99(100个)
    console.log(99-n); // 倒序打印出99~0(100个)
  }).call(null, n), Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++) {
  // console.log(i) // 0~99
  print(i); 
}
console.log(i) // 注意:此时i在全局window里可访问到,值为100

@haipingzi
Copy link

function print(n) {
setTimeout(async ()=>{
await new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(n)
},n*1000)
});
console.log(n)
},Math.floor(Math.random()*100))
}

for(var i=0;i<100;i++){
print(i)
}

@haipingzi
Copy link

利用异步函数也可以,这个简单直接

@Chorer
Copy link

Chorer commented Jul 9, 2019

// 方法1 利用for的变量i  输出99-0
function print(n){
  setTimeout(() => {
    console.log(--i);
  }, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

//方法2 将setTimeout 的时间改为 0*Math.floor(Math.random() * 1000) .. 取巧了一下
// 输出0-99
function print(n){
  setTimeout(() => {
    console.log(n);
  }, 0*Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

请问第二个方法不是异步的吗,最后为什么不是都打印99呢?

@gongtiexin
Copy link

gongtiexin commented Jul 9, 2019

function print(n) {
setTimeout(() => {
console.log(n);
}, n * 1001 + Math.floor(Math.random() * 1000));
}
for (var i = 0; i < 100; i++) {
print(i);
}
不知道这样违规没有 🌚

@kungithub
Copy link

// 方法1 利用for的变量i  输出99-0
function print(n){
  setTimeout(() => {
    console.log(--i);
  }, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

//方法2 将setTimeout 的时间改为 0*Math.floor(Math.random() * 1000) .. 取巧了一下
// 输出0-99
function print(n){
  setTimeout(() => {
    console.log(n);
  }, 0*Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

请问第二个方法不是异步的吗,最后为什么不是都打印99呢?

这是当做参数传到print方法的,正真执行print方法的时候i参数就是当时的i的值

@liuliudaren
Copy link

liuliudaren commented Jul 23, 2019

function print(n){
setTimeout((() => {
console.log(n)
})(), Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
print(i);
}
将setTimeout的第一个参数改为自执行就可以了

@felaofan
Copy link

思路很清晰,把setTimeout的第二个参数改为n

function print(n){
  setTimeout(() => {
    console.log(n);
  },n, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

@3N26
Copy link

3N26 commented Aug 2, 2019

function print(n){
setTimeout(() => {
setTimeout(() => {
console.log(n);
}, n*1000)
}, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
print(i);
}

@BellaGuan
Copy link

@Chenxinan 你这个只要把Math.floor(Math.random() * 1000)改成Math.floor(Math.random() * 10000)就不会按顺序输出0-99。

@BellaGuan
Copy link

@Hunterang 恩恩,感觉这题是想考核面试者在不用promise.all()的情况下,在并发100次请求后,如何把浏览器在不同时间点获取到的数据按原先的数据逻辑顺序输出。

@my-illusion
Copy link

function print(n){
setTimeout(() => {
if(n !== 99){
setTimeout(() => { console.log(n) }, 1000 + (99 - n) * 1000)
}else{
console.log(n);
}
}, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
print(i);
}

@helloyoucan
Copy link

helloyoucan commented Aug 14, 2019

// 0~99
function print(n){
	setTimeout(() => {
	 	setTimeout(()=>{
	 		console.log(n);
	 	},n*1000)
	}, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
	print(i);
}
// 99-0
function print(n){
	setTimeout(() => {
	 	setTimeout(()=>{
	 		console.log(n);
	 	},(100-n)*1000)
	}, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
	print(i);
}

第二种,去掉setTimeout

function print(n){
	((() => {
	 	console.log(n);
	})(), Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
	print(i);
}

@daiyunchao
Copy link

function print(n){
	setTimeout(()=>{
		console.log(n);
	},(n*1000)+Math.floor(Math.random()*1000))
}
for(var i=0;i<100;i++){
	print(i)
}

@SoftwareEngineerPalace
Copy link

function print(n){
  setTimeout((() => {
    console.log(n)
    return ()=>{}
  }).call(n,[]), Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

理是?没看懂

@renshunli
Copy link

我去脑筋急转弯的题

@yaodongyi
Copy link

function print(n) {
  setTimeout((i => {
      console.log(i);
    })(i),Math.floor(Math.random() * 1000)
  );
}
for (var i = 0; i < 100; i++) {
  print(i);
}

@lzxxxxx
Copy link

lzxxxxx commented Oct 11, 2019

看了各位的解法我觉得自己的解法跟闹着玩似的…… 在每一次执行前重写了 Math.random…………

function print(n){
  setTimeout((function(){
    Math.random = function(){
      return 0.1 * n;
    }
    return (() => {
    console.log(n);
  })})(), Math.floor(Math.random() * 1000));
}

@aeolusheath
Copy link

        //  方法一
        function print(n) {
          setTimeout(() => {
            // console.log(n);
            let i = n
            setTimeout(() => {
              console.log(i, 'ddd')
            }, n * 1000)
          },
            Math.floor(Math.random() * 1000)
          );
        }
        for (var i = 0; i < 100; i++) {
          print(i);
        }

        // 方法二
        function print(n) {
          setTimeout(() => {
            // console.log(n);
            setTimeout((i) => {
              console.log(i)
            }, n * 1000, n)
          },
            Math.floor(Math.random() * 1000)
          );
        }
        for (var i = 0; i < 100; i++) {
          print(i);
        }



        // 方法三  立即执行函数,相当于同步代码
        function print(n){
          setTimeout((()=>{
            console.log(n)
            return ()=>{}
          })(), Math.floor(Math.random() * 1000));
        }
        for(var i = 0; i < 100; i++){
          print(i);
        }

@niannings
Copy link

换一种思路

function print(n){
  setTimeout(() => {
    if (!print.cache) {
      print.cache = [];
      print.id = null;
    };
    print.cache.push(n);
    clearTimeout(print.id);
    print.id = setTimeout(() => {
      print.cache.sort((a, b) => a - b);
    	for (let num of print.cache) {
      	console.log(num);
      }
      delete print.id;
      delete print.cache;
      // 最长不过1000ms
    }, 1000);
  }, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
	print(i);
}

@Murphycx94
Copy link

感觉无论是立即执行函数、表达式,还是用n去替代Math.random,脱离了题目本身的意义。所以考的是脑筋急转弯?

@Murphycx94
Copy link

function print(n){
setTimeout(() => {
setTimeout(() => { console.log(n) }, n * 1000)
}, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
print(i);
}

@alan1111
Copy link

alan1111 commented Jul 1, 2020

image

@crabkiller
Copy link

支持原题中间隔随机时间 print 的版本

(() => {
  function print(n) {
    setTimeout(
        (() => {
        // const prev = i.__proto__.prev;
        const prev = print.prev;
        let resolver = () => {};
        // i.__proto__.prev = new Promise(resolve => {
        print.prev = new Promise(resolve => {
          resolver = resolve;
        });
        const exec = (delay) => {
          setTimeout(() => {
            console.log(n);
            resolver();
          }, delay);
        };

        return prev
          ? (delay) => {
            prev
              .then(exec.bind(null, delay))
              .then(() => {
                // if (i.__proto__.prev) {
                if (print.prev) {
                  // delete i.__proto__.prev;
                  delete print.prev;
                }
              });
          }
          : exec;
      })(),
      0,
      Math.floor(Math.random() * 1000)
    );
  }
  for (var i = 0; i < 100; i++){
    print(i);
  }
})()

@XuedaoYuan
Copy link

不知道这燕子算不算满足要求

function print(n) {
	setTimeout(() => {
		if (!print.index && print.index !== 0) {
			print.index = 99
		} else {
			print.index--
		}
		console.log(print.index)
	}, Math.floor(Math.random() * 1000))
}
for (var i = 0; i < 100; i++) {
	print(i)
}

@xxleyi
Copy link

xxleyi commented Oct 31, 2020

还可以利用逗号表达式 :-)

但我实在搞不懂这题的目的是啥?

function print(n){
  setTimeout((console.log(n), () => null), Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

@auyo18
Copy link

auyo18 commented Nov 10, 2020

function print(n) {
    setTimeout(() => {
      if (!print.list) print.list = []
      if (!print.timer)
        print.timer = setTimeout(() => {
          print.list.forEach(fn => fn())
        }, 1000)
      print.list[n] = () => console.log(n)
    }, Math.floor(Math.random() * 1000))
  }

  for (var i = 0; i < 100; i++) {
    print(i)
  }

@blank1u
Copy link

blank1u commented Dec 14, 2020

function print(n) {
    setTimeout((function () {
        console.log(n);
        return () => { }
    })(), Math.floor(Math.random() * 1000));
}
for (var i = 0; i < 100; i++) {
    print(i);
}

@liaoqinwei
Copy link

`function print(n) {
setTimeout(() => {
console.log(100 - i--);
}, Math.floor(Math.random() * 1000));
}

for (var i = 0; i < 100; i++) {
print(i);
}`

@zhangtaolei
Copy link

词法环境与闭包的联系:
静态作用域
动态作用域

function print(n){
  setTimeout((() => {
    console.log(n);
    return ()=>{}
  })(), Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

@Joker-Qu
Copy link

function print(n){
setTimeout(() => {
console.log(n)
}, 0 , Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
print(i);
}

@Lingdeqing
Copy link

0~99

function print(n){
  setTimeout((() => {
    console.log(99);
      return () => {}
  })(), Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

99~0

function print(n){
  setTimeout((() => {
    console.log(99-n);
      return () => {}
  })(), Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}

@Yangfan2016
Copy link

利用 settimeout 的第一个参数 可以传 表达式 的原理,绕过了 随机的定时器执行

function print(n){
    setTimeout((console.log(n),()=>{}),Math.floor(Math.random()*1000));
}

for(var i = 0; i < 100; i++){
  print(i);
}

@xiaobinniu
Copy link

function print(n){
  setTimeout(() => {
    console.log(n);
  }, 1, Math.floor(Math.random() * 1000));
}
for(var i = 0; i < 100; i++){
  print(i);
}
```机智

@rongda
Copy link

rongda commented Nov 17, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests