书写一个数组去重的方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 function deduplication (array ) { return Array .from (new Set (array)); } function deduplication (array ) { let obj = {}, result = []; for (let i = 0 ; i< array.length ; i++){ if (!obj[array[i]]){ obj[array[i]] = 1 ; result.push (array[i]); } } return result; }; function deduplication (array ) { let result = []; array.forEach (function (item, index ,arr ){ if (arr.indexOf (item, index + 1 ) < 0 ) { result.push (item); } }); return result; }; function deduplication (array ){ var result = []; for (let i = 0 ; i < array.length ; i++){ for (let j = i + 1 ; j < array.length ; j++){ if (array[i] === array[j]){ j = ++i; } } result.push (array[i]); } return result; } function deduplication (array ){ let len = array.length ; for (let i = 0 ; i < len; i++){ for (let j = i + 1 ; j < len; j++){ if (array[i] == array[j]){ array.splice (j, 1 ); len--; j--; } } } return array; };
书写将数组打乱顺序的方法 1 2 3 4 5 6 Array .prototype .disorder = function ( ) { return this .sort ((a, b ) => { return Math .random () > .5 ? 1 : -1 ; }); }
1 2 3 4 5 6 7 8 9 10 Array .prototype .shuffle = function ( ) { for (var j, x, i = this .length - 1 ; i; i--) { j = parseInt (Math .random () * i); x = this [i]; this [i] = this [j]; this [j] = x; } return this ; };
书写一个方法将一个字符串倒序输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 String .prototype .reverse = function ( ) { return this .split ('' ).reverse ().join ('' ); } String .prototype .reverse = function ( ) { return Array .prototype .reduceRight .call (this , function (result, char ) { return result += char; }, '' ); } String .prototype .reverse = function ( ) { var result = '' ; for (var i = this .length - 1 ; i >=0 ; i--) { result += this .charAt (i); } return result; }
书写一个方法使用reduce模拟map/使用map来模拟reduce 使用reduce模拟map1 2 3 4 5 6 7 8 9 10 11 Array .prototype ._map = function (fn, callbackThis ) { let CBThis = callbackThis || null ; return this .reduce ((res, ele, idx, arr ) => { res.push (fn.call (CBThis , ele, idx, arr)); return res; }, []); };
解析url,将url中的参数转化为对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function getQueryString (name ) { var reg = new RegExp ("(^|&)" + name + "=([^&]*)(&|$)" , "i" ); var r = window .location .search .substr (1 ).match (reg); if (r != null ) return unescape (r[2 ]); return null ; } function GetRequest ( ) { var url = location.search ; var theRequest = new Object (); if (url.indexOf ("?" ) != -1 ) { var str = url.substr (1 ); strs = str.split ("&" ); for (var i = 0 ; i < strs.length ; i ++) { theRequest[strs[i].split ("=" )[0 ]] = unescape (strs[i].split ("=" )[1 ]); } } return theRequest; }
循环体中不含有break语句时使用while循环来模拟for循环 for循环:1 for (initialize; test; increment)body;
while循环:1 2 3 4 5 initialize; while (test) { try { body;} finally { increment;} }
试写出 bind() 的 polyfill 方法 MDN上的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 if (!Function .prototype .bind ) (function ( ){ var slice = Array .prototype .slice ; Function .prototype .bind = function ( ) { var thatFunc = this , thatArg = arguments [0 ]; var args = slice.call (arguments , 1 ); if (typeof thatFunc !== 'function' ) { throw new TypeError ('Function.prototype.bind - ' + 'what is trying to be bound is not callable' ); } return function ( ){ var funcArgs = args.concat (slice.call (arguments )) return thatFunc.apply (thatArg, funcArgs); }; }; })();
实现 emit/on 观察者模式 发布/订阅模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 var Event = (function ( ){ var list = {}, on, emit, remove; on = function (key,fn ){ if (!list[key]){ list[key] = []; } list[key].push (fn); }; emit = function ( ){ var key = Array .prototype .shift .call (arguments ); msg = list[key]; if (!msg || msg.length === 0 ){ return false ; } for (var i = 0 ; i < msg.length ; i++){ msg[i].apply (this , arguments ); } }; remove = function (key, fn ){ var msg = list[key]; if (!msg){ return false ; } if (!fn){ delete list[key]; }else { for (var i = 0 ; i < msg.length ; i++){ if (fn === msg[i]){ msg.splice (i, 1 ); } } } }; return { on : on, emit : emit, remove : remove } })(); var fn = function (data ){ console .log (data + '的推送消息:xxxxxx......' ); } Event .on ('action' , fn);Event .emit ('action' , '2016.11.26' );Event .remove ('action' );
对象object深拷贝 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 export function isObject (obj ) { return (typeof obj === 'object' ) && (obj !== null ); } export function deepClone (source ) { if (!isObject (source)) { return source; } let target = Array .isArray (source) ? [] : {}; Object .entries (source).forEach (([key, val] ) => { target[key] = deepClone (val); }); return target; }
判断两个对象内容是否一样 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 export function isObjectValueEqual (a, b ) { if (!isObject (a) || !isObject (b)) { return a === b; } if (Object .keys (a).length !== Object .keys (b).length ) { return false ; } let target = true ; Object .entries (a) .forEach (([key, val] ) => { if (!isObjectValueEqual (a[key], b[key])) { target = false ; return ; } }); return target; }
如下代码,分别弹出什么信息? 1 2 3 4 5 6 7 8 9 var a = 100 ;function create ( ) { var a = 200 ; return function ( ) { console .log (a) } } var fn = create ()fn ();
1 2 3 4 5 6 7 8 9 var a = 100 ;function invoke (fn ) { var a = 200 ; fn (); } function fn ( ) { console .log (a); } invoke (fn)
返回 200 100 函数的执行依赖于变量作用域,这个作用域是函数定义时决定的。 第一段代码中 fn 实际是 create() 函数返回的函数,这个函数中使用的 a 是 create() 函数中定义的 a 变量,它覆盖了外部定义的 a。 第二段代码中 fn 在 invoke 函数外部定义,这个函数中的 a 是外部定义的 a,所以即使通过 invoke 函数包了一层,还是会返回外部定义的 a。 第二段代码也可以通过将 a 作为 fn 的 入参来使用,这样入参 a 就可以覆盖外部的 a。
1 2 3 4 5 6 7 8 9 var a = 100 ;function invoke (fn ) { var a = 200 ; fn (a); } function fn (a ) { console .log (a); } invoke (fn)
以上代码返回 200
现有瀑布流式页面(页面下拉式无限加载图片),用js监听每个图片的点击事件 采用事件委托的方式实现
执行如下代码,然后点击每个 a 标签分别弹出什么信息?并写明原因 1 2 3 4 5 6 7 8 9 10 let $body = $('body' )let arr = [1 ,2 ,3 ,4 ,5 ]let i,length = arr.length , $afor (i=0 ; i<length; i++) { $a = $(`<a>${i} </a>` ) $body.append ($a) $a.click (function ( ) { alert (i) }) }
弹出5,因为click绑定了的方法弹出i,i循环结束时为5.若想输出 0 1 2 3 4,可将绑定方法改为自执行函数形成闭包。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 let $body = $('body' )let arr = [1 ,2 ,3 ,4 ,5 ]let i,length = arr.length , $afor (i=0 ; i<length; i++) { $a = $(`<a>${i} </a>` ) $body.append ($a); (function (i ) { $a.click (function ( ) { alert (i) }) })(i) }
执行下面代码会输出什么信息? 1 2 3 4 5 6 7 8 9 10 11 12 const obj = { a : 100 } const obj1 = obj;let a1 = obj.a ;obj1.a = 200 ; console .log (obj.a );console .log (a1);a1= 300 ; console .log (obj.a );console .log (obj1.a )
200 100 200 200
执行如下代码会输出什么信息? 1 2 3 4 5 6 7 8 setTimeout (function ( ) { console .log (100 ) }) console .log (200 )Promise .resolve ().then (function ( ){ console .log (300 ) });
200 300 100
同步代码最先执行 Promise 属于 microTask 第二个执行 setTimeout 属于 macroTask 最后执行
执行如下代码,分别打印出什么? 1 2 3 123 instanceof Number new Number (123 ) instanceof Number Number (123 ) isntanceof Number
false ture false
第一个 首先左侧为number类型,并不是一个对象,更不是由 Number 实例化出来的(基本包装类型),所以为false 第二个 左侧使用 Number 构造实例化对象 右侧为 Number 构造 ,所以为true 第三个 左侧没有使用 new 所以并不是使用构造函数实例化 而是使用 Number 这个函数返回了一个数字, 所以为false
写一个方法返回入参类型 number string boolean null undefined object symbol(ES6) bigint(ES2020)
如果只需要返回基本数据类型:
1 2 3 function typeOf (value ) { return value === null ? 'null' : (typeof value === 'function' ? 'object' : typeof value); }
如果需要返回类型:
1 2 3 function typeOf (param ) { return Object .prototype .toString .call (param).splice (8 , -1 ); }
写一个方法完成如下输入输出 输入为一个二维数组,每一项都是由两个 string 组成的数组,将输入参数的每一项与其他项相拼接,返回扁平化的数组。 输入: [[‘a’, ‘b’], [‘n’, ‘m’], [‘0’, ‘1’]] 输出:[‘an0’, ‘an1’, ‘am0’, ‘am1’, ‘bn0’, ‘bn1’, ‘bm0’, ‘bm1’]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 let input = [['a' , 'b' ], ['n' , 'm' ], ['0' , '1' ]];function flatArr (param ) { let result = ['' ]; param.forEach (element => { result = result.reduce ((res, ele ) => { res.push (ele + element[0 ], ele + element[1 ]); return res; }, []); }); console .log (result); return result; } flatArr (input);
写一个方法按照层级将对象进行扁平化处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 var object = { a : { b : { c : { d : 'e' } } }, f : { a : { x : null } }, i : ['a' , 'v' ], k : { l : 'm' } }; [['a' , 'f' , 'i' , 'k' ], ['b' , 'a' , 'l' ], ['c' , 'x' ], ['d' ]]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 let result = [];function isObj (obj ) { return typeof obj === 'object' && obj !== null && !Array .isArray (obj); } function flatObj (obj, n ) { if (!isObj (obj)) { return ; } for (let key in obj) { if (!result[n]) { returl[n] = []; } result[n].push (key); flatObj (obj[key], n + 1 ); } } flatObj (object, 0 );console .log (result);
实现 sleep 方法 1 2 3 4 5 6 7 function sleep (time, callback ) { setTimeout (callback, time); } sleep (10000 , () => { });
1 2 3 4 5 function sleep (time ) { let _start = new Date ().getTime (); while (new Date ().getTime () - _start < time); }
写一个方法进行对输入参数进行累加,入参多于5个时输出
使用全局变量和递归1 2 3 4 5 6 7 8 9 10 let count = 0 ;let result = 0 ;function add ( ) { Array .prototype .forEach .call (arguments , item => { result += item; count += 1 ; }); return count < 5 ? add : result; } console .log (add (1 ,2 ,3 )(4 ,5 ,6 ));
使用闭包1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function add ( ) { let count = 0 ; let result = 0 ; function append ( ) { count += arguments .length ; result += +eval (Array .prototype .join .call (arguments , '+' )); return count < 5 ? append : result; } return append (...arguments ); } console .log (add (1 )(2 )(3 )(4 )(5 ));
连续正整数数组,去掉中间一个数字之后乱序,求去掉的数字 使用排序和循环遍历 时间复杂度为 O(nlogn + n) = O(nlogn)1 2 3 4 5 6 7 8 9 10 11 let input = [2 ,4 ,6 ,8 ,7 ,3 ];function find (param ) { let result = param.sort (); result.forEach ((element, idx ) => { if (element + 1 !== result[idx + 1 ] && idx !== result.length -1 ) { return element + 1 ; } }) } console .log (find (input));
利用数组下标 时间复杂度为 O(2n) = O(n)1 2 3 4 5 6 7 8 9 10 11 12 let input = [2 ,4 ,6 ,8 ,7 ,3 ];function find (param ) { let tmp = []; param.forEach (item => { tmp[item] = 1 ; }); for (let i = tmp.length - 1 ; i >= 0 ; i--) { if (!tmp[i]) return i; } } console .log (find (input));
如果连续正整数从1开始(或者知道起始位置),可以从数组的和来获知 只需要遍历一次,时间复杂度为 O(n)1 2 3 4 5 function find (param ) { let n = param.length + 1 ; return n * (n + 1 ) / 2 - param.reduce ((result, item ) => {return result + item;}, 0 ); } console .log (find (1 ,2 ,4 ,6 ,8 ,7 ,3 ));
合并两个长度很大的数组
使用 concat
concat 方法连接a、b两个数组后,a、b 两个数组的数据不变,同时会返回一个新的数组。如果 a、b 合并后不再使用,因为 a、b 数据量大会该方法会占用较多内存。
使用循环 + push
遍历其中一个数组,把该数组中的所有元素依次添加到另外一个数组中
1 2 3 b.forEach (item => { a.push (item); });
在循环之前可以先比较下 a、b 的长度,对短的进行循环,减少遍历插入次数。
使用 push.apply
Function.prototype.apply
的第二个参数是数组,利用该特性,可以简化循环写法
取得当前正在执行的function的名字 可以从 arguments.callee 中获取到
如果支持 name
1 2 3 function fn ( ) { let funcName = arguments .callee .name ; }
否则可以通过正则匹配
1 2 3 4 5 6 7 function getFuncName (fn ){ return (/^[\s\(]*function(?:\s+([\w$_][\w\d$_]*))?\(/ ).exec (fn.toString ())[1 ] || '' ; } function test ( ){ getFuncName (arguments .callee ); }
但是严格模式中无法获取callee
也可以从 Error 的错误堆栈中获取当前 function 名字
1 2 3 4 function getExecFunctionName ( ) { let names = new Error ().stack .match (/at (.*?) /g ); return names[1 ].replace ('at ' , '' ).trim (); }
以下代码的输出顺序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 console .log ('a' );async function async1 ( ) { await async2 (); console .log ('b' ); } async function async2 ( ) { console .log ('c' ); } async1 ();setTimeout (() => { console .log ('d' ); }, 0 ); Promise .resolve ().then (() => { console .log ('i' ); }).then (()=> { console .log ('j' ); }); new Promise ((resolve ) => { console .log ('e' ); resolve (); }).then (() => { console .log ('f' ); }).then (() => { console .log ('g' ); }); console .log ('h' );
同步 a c e h /异步microTask b i f j g / 异步macroTask d
输出一个字符串中不重复的连续字符串的最大长度 例如 abcddbca
,其中符合的字符串为 abcd 和 dbca, 所以需要输出 4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function getNum (str ) { let maxLen = 0 ; const strArr = str.split ('' ); strArr.forEach ((char, idx ) => { let tmpArr = [char]; for (let i = idx + 1 ; i < strArr.length ; i++) { if (!tmpArr.includes (strArr[i])) { tmpArr.push (strArr[i]); } else { break ; } } if (tmpArr.length > maxLen) { maxLen = tmpArr.length ; } }); return maxLen; }
判断一个字符串是否是回文字符串 需要将字符串先将大写转换成小写,去除符号和数字,如果从前往后和从后往前都是同样的,则是回文字符串。
例如 001ABCD,dcba.
是回文字符串
1 2 3 4 5 6 7 8 function isRightStr (str ) { let str1 = str.toLowerCase ().replace (/[0-9\s,.]+/g , '' ); for (let i = 0 ; i < Math .floor (str1.length / 2 ) + 1 ; i++) { if (str1[i] !== str1[str1.length - i - 1 ]) return false ; } return true ; }
点击inner元素输出结果 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 <div class ="outer" > <div class ="inner" > </div > </div > <style > .outer { width : 200px ; height : 200px ; background : red; } .inner { width : 100px ; height : 100px ; background : green; } </style > <script > var outer = document .querySelector ('.outer' ); var inner = document .querySelector ('.inner' ); new MutationObserver (function ( ) { console .log ('mutate' ); }).observe (outer, { attributes : true , }); function onClick (e ) { console .log ('click' ); setTimeout (function ( ) { console .log ('timeout' ); }, 0 ); Promise .resolve ().then (function ( ) { console .log ('promise' ); }); outer.setAttribute ('data-random' , Math .random ()); } inner.addEventListener ('click' , onClick); outer.addEventListener ('click' , onClick); </script >
结果: click promise mutate click promise mutate timeout timeout
步骤:
点击 inner 触发 inner 元素的 onClick 入栈 macroTask
触发 outer 元素的 onclick 入栈 macroTask —- microTask 为空,执行 macroTask
执行 onClick 方法中的 console.log('click')
打印 click
setTimeout() 中的 console.log('timeout')
入栈 macroTask
Promise.resolve().then() 中的 console.log('promise')
入栈 microTask
outer.setAttribute('data-random', Math.random());
变更了 outer 的 attritube 触发了 MutationObserver(), 导致 console.log('mutate')
入栈 microTask —- 执行 microTask
打印 promise , 打印 mutate —- microTask 为空,执行 macroTask
执行 onClick, 按照 3-7 执行一遍 —- 执行 macroTask
打印 timeout —- 执行 macroTask
打印 timeout
限制并发数量的多请求执行 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 function request (options ) { return new Promise ((resolve, reject ) => { console .log (`${options} is start` ) setTimeout (() => { console .log (`${options} is finished` ) resolve ({ data : options }); }, 3000 ); }); } function fetch (options ) => { request (options).then ((res ) => { }).catch ((err ) => { }); } function parallelRequest (optionsList ) { return Promise .all (optionsList.map (options => request (options))); } parallelRequest ([1 ,2 ,3 ]).then (data => { console .log (data); }); async function serialRequest (optionsList ) { let res = []; for (let i = 0 ; i < optionsList.length ; i++) { let result = await request (optionsList[i]); res.push (result); } return Promise .resolve (res); } serialRequest ([1 ,2 ,3 ]).then (data => { console .log (data); }); function multiRequest (optionsList = [], maxNum ) { const len = optionsList.length ; const result = new Array (len).fill (false ); let count = 0 ; return new Promise ((resolve, reject ) => { while (count < maxNum) { next (); } function next ( ) { let current = count++; if (current >= len) { !result.includes (false ) && resolve (result); return ; } const options = optionsList[current]; request (options) .then ((res ) => { result[current] = res; if (current < len) { next (); } }).catch ((err ) => { result[current] = err; if (current < len) { next (); } }); } }); } multiRequest ([1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ], 3 ).then (res => { console .log (res); }); class LimitRequest { constructor (limit ) { this .limit = limit; this .tasks = []; this .current = 0 ; } addRequest (reqFn ) { if (!reqFn || !(reqFn instanceof Function )) { console .error ('当前请求不是一个Function' ); return ; } this .tasks .push (reqFn); if (this .current < this .limit ) { this .run (); } } async run ( ) { try { this .current ++; const fn = this .tasks .shift (); await fn (); } catch (err) { throw new Error (err); } finally { this .current --; if (this .tasks .length > 0 ) { this .run (); } } } } let limitRequest = new LimitRequest (3 );limitRequest.addRequest (fetch.bind (null , '1' )); limitRequest.addRequest (fetch.bind (null , '2' )); limitRequest.addRequest (fetch.bind (null , '3' )); limitRequest.addRequest (fetch.bind (null , '4' )); limitRequest.addRequest (fetch.bind (null , '5' )); limitRequest.addRequest (fetch.bind (null , '6' )); limitRequest.addRequest (fetch.bind (null , '7' )); limitRequest.addRequest (fetch.bind (null , '8' )); limitRequest.addRequest (fetch.bind (null , '9' )); limitRequest.addRequest (fetch.bind (null , '10' ));
优化下,无需每次都 bind
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 class LimitRequest { constructor (limit ) { this .limit = limit; this .tasks = []; this .current = 0 ; } request (options ) { return new Promise ((resolve, reject ) => { let reqFn = request.bind (null , options); this .tasks .push ([reqFn, resolve, reject]); if (this .current < this .limit ) { this .run (); } }); } async run ( ) { try { this .current ++; const [fn, resolve, reject] = this .tasks .shift (); await fn ().then (res => { resolve (res); }).catch (err => { reject (err); }); } catch (err) { throw new Error (err); } finally { this .current --; if (this .tasks .length > 0 ) { this .run (); } } } } let limitRequest = new LimitRequest (3 );let newRequest = limitRequest.request .bind (limitRequest);newRequest ('1' ).then (console .log );newRequest ('2' ).then (console .log );newRequest ('3' ).then (console .log );newRequest ('4' ).then (console .log );newRequest ('5' ).then (console .log );newRequest ('6' ).then (console .log );newRequest ('7' ).then (console .log );newRequest ('8' ).then (console .log );newRequest ('9' ).then (console .log );newRequest ('10' ).then (console .log );
utils写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 const limit = 3 ; let tasks = []; let current = 0 ; export function newRequest (options ) { return new Promise ((resolve, reject ) => { let reqFn = request.bind (null , options); tasks.push ([reqFn, resolve, reject]); if (current < limit) { run (); } }); } async function run ( ) { try { current++; const [fn, resolve, reject] = this .tasks .shift (); await fn ().then (res => { resolve (res); }).catch (err => { reject (err); }); } catch (err) { throw new Error (err); } finally { current--; if (tasks.length > 0 ) { run (); } } } newRequest ('1' ).then (console .log );newRequest ('2' ).then (console .log );newRequest ('3' ).then (console .log );newRequest ('4' ).then (console .log );newRequest ('5' ).then (console .log );newRequest ('6' ).then (console .log );newRequest ('7' ).then (console .log );newRequest ('8' ).then (console .log );newRequest ('9' ).then (console .log );newRequest ('10' ).then (console .log );
版本号比较 1 2 3 4 5 6 7 8 9 10 11 12 function compareVersion (version1, version2 ) { let arr1 = version1.split ('.' ); let arr2 = version2.split ('.' ); let len = Math .max (arr1.length , arr2.length ); for (let i = 0 ; i < len; i++) { const n1 = Number (arr1[i]||0 ); const n2 = Number (arr2[i]||0 ); if (n1 > n2) return 1 ; if (n1 < n2) return -1 ; } return 0 ; }
m 个红球, n 个白球,依次全部取出,求共有多少种不同的取出顺序 即求概率论中C(m+n)n
1 2 3 4 5 6 7 8 9 10 11 12 13 function factorial (number ) { let result = 1 ; if (number === 0 ||number === 1 ) return 1 ; for (let i = 2 ; i <= number; i++) { result *= i; } return result; } function getNum (m, n ) { return factorial (m + n)/factorial (m)/factorial (n); }