JS笔试题——编程题 (数组去重、去空格、找冲重复、深拷贝、防抖节流、素数、平年闰年、new、promise)

目录

1、将 "hqyj-is-good" 字符串  转为:  "hqyjIsGood"

2、找出数组中最大的元素

3、随便传入一个字符串 找出重复的次数,并返回下标

4、去掉头尾和全部的空格

5、

6、第一个字母变大写

7、设计myforEach

8、设计mysome

9、判断自循环重复次数或者是否存在 (是否存在:indexOf和match两种方法)

10、编写一段程序代码,获取今天的日期,格式如“2021-01-01”;并计算下一周同一天的日期。

11、修改以下代码,使其按照意图输出0,1,2,3,4

12、下面代码输出的内容是

13、使用es6 合并两个对象

14、 下面输出内容是

15、获取input框中的value值

16、封装一个方法,实现原生JS兼容各类浏览器的元素事件绑定?

17、数组去重--11种方法

18、深拷贝

19、防抖节流

20、判断素数 + `求1到100以内素数`

21、判断是否平年闰年

22、找出字符串中指定字母下标 , 次数

23、实现new关键字

24.实现promise关键字

25、输入一行字符串,由英文字母、数字、和空格组成,并以换行符结尾,其中大写字母、小写字母、数字和空格出现的次数、并依次输出

26、给定N个整数,请你依次输出第一大的数与第一小的数之和,第二大的数与第二小的数之和,第三大的数与第三小的数之和(如果N为奇数,中位数不必输出)


1、将 "hqyj-is-good" 字符串  转为:  "hqyjIsGood"

    //方法一:
        var str = "hqyj-is-good"
        var arr = str.split("-")
        re = arr[0] + arr[1][0].toUpperCase() + arr[1][1] + arr[2][0].toUpperCase() + arr[2][1] + arr[2][2] + arr[2][3]
        console.log(re)

        //方法二
        var str = "hqyj-is-good"
        String.prototype.myparse = function (str) {
            var arrStr = str.split('-')
            for (var i = 1; i < arrStr.length; i++) {
                arrStr[i] = arrStr[i].substr(0, 1).toUpperCase() + arrStr[i].substr(1)
            }
            return arrStr.join("")
        }
        var str2 = str.myparse(str)
        console.log(str2)

        //方法三:
        String.prototype.myparse = function (str) {
            var arr = this.split("-")
            var arr2 = arr[1].split("")
            var re = arr2[0].toUpperCase()
            for (var i = 1; i < arr2.length; i++) {
                re += arr2[i]
            }
            var arr3 = arr[2].split("")
            var rel = arr3[0].toUpperCase()
            for (var j = 1; j < arr3.length; j++) {
                rel += arr3[j]
            }
            var arr4 = arr[0].concat(re, rel)
            return arr4
        }
        var str = "hqyj-is-good"
        var str2 = str.myparse()
        console.log(str2)

        //方法四:
        var str = "hqyj-is-good"

        function myparse(str) {
            var arrStr = str.split('-')
            for (var i = 1; i < arrStr.length; i++) {
                arrStr[i] = arrStr[i].substr(0, 1).toUpperCase() + arrStr[i].substr(1)
            }
            return arrStr.join("")
        }
        console.log(myparse(str))

2、找出数组中最大的元素

 //方法一:
        var arr = [10, 4, 2, 5, 30, 1]
        var maxnum = Math.max.apply(0, arr)
        console.log(maxnum)

        //方法二:js中的sort()方法
        var arr = [10, 4, 2, 5, 30, 1]
        var re = arr.sort(function (a, b) {
            return b - a
        })
        console.log(re[0])

        //方法三:
        Array.prototype.mymax = function () {
            this.sort(function (a, b) {
                return b - a
            })
            return this[0]
        }
        var arr = [10, 2, 3, 5, 30, 1]
        var re = arr.mymax()
        console.log(re)

        //方法四
        var arr = [10, 4, 2, 5, 30, 1]
        var max3 = -Infinity;
        for (var i = 0; i < arr.length; i++) {
            if (max3 < arr[i]) {
                max3 = arr[i];
            }
        }
        console.log(max3)

        //方法五:
        Array.prototype.mymax = function(arr) {
            for (var i=0;i<this.length;i++) {
                var a=this[i]
                var b = this[i+1]
                var arr2=this.sort(function(a,b) {
                    var rel = b-a
                    return rel
                })
            }
            return arr2[0]
        }
        var arr=[10,2,3,5,30,1]
        var re=arr.mymax()
        console.log(re)

        //方法六
        var arr=[1,2,3]
        var arrMax=Math.max(...arr)
        console.log(arrMax)

//方法七: 选择排序`
var arr = [123,203,23,13,34,65,65,45,89,13,1];
for(var i=0;i<arr.length;i++){
	for(var j=i+1;j<arr.length;j++){
		//如果第一个比第二个大,就交换他们两个位置
		if(arr[i]>arr[j]){
			var temp = arr[i];
			arr[i] = arr[j];
			arr[j] = temp;
		}
	}
}
console.log(arr); //(11) [1, 13, 13, 23, 34, 45, 65, 65, 89, 123, 203]

//方法八: 冒泡排序`
var arr = [123,203,23,13,34,65,65,45,89,13,1];
for(var i=0; i<arr.length-1; i++){
	//每一轮比较要比多少次
	for(var j=0; j<arr.length-1-i; j++){
	    //如果第一个比第二个大,就交换他们两个位置
	    if(arr[j]>arr[j+1]){
	        var temp = arr[j];
	        arr[j] = arr[j+1];
	        arr[j+1] = temp;
	    }
	}    
}
console.log(arr); //(11) [1, 13, 13, 23, 34, 45, 65, 65, 89, 123, 203]

//方法九: 插入排序`
var arr = [123,203,23,13,34,65,65,45,89,13,1];
var preIndex, current;
for(var i=1;i<arr.length;i++){
	preIndex = i-1;
	current = arr[i];
	while(preIndex>=0 && arr[preIndex]>current) {
	    arr[preIndex+1] = arr[preIndex];
	    preIndex--;
	}
	arr[preIndex+1] = current;
}
console.log(arr); //(11) [1, 13, 13, 23, 34, 45, 65, 65, 89, 123, 203]

//方法十: 快速排序`
var arr = [123,203,23,13,34,65,65,45,89,13,1];	
//创建快速排序函数
function quickSort(tempArr){
	//递归终止条件
	if(tempArr.length<=1){
		return tempArr;
	};
	//取基准
	var pivotIndex = Math.floor(tempArr.length/2);
	var pivot = tempArr.splice(pivotIndex,1);
	//分左右
	var leftArr = [];
	var rightArr = [];
	for(var i=0;i<tempArr.length;i++){
		if(tempArr[i]>pivot){
			rightArr.push(tempArr[i]);
		}else{
			leftArr.push(tempArr[i]);
	    };
	};
	return quickSort(leftArr).concat(pivot,quickSort(rightArr));
};
console.log(quickSort(arr)); //(11) [1, 13, 13, 23, 34, 45, 65, 65, 89, 123, 203]

3、随便传入一个字符串 找出重复的次数,并返回下标

        //方法一
        String.prototype.count1 = function (str) {     //方法一
            var re = -1;
            var count = 0
            var arr = []
            do {
                re = this.indexOf(str, re + 1)
                if (re != -1) {
                    count++, arr.push(re)
                }
            } while (re != -1)
            return (count, arr)
        }
        var str = "abcdqwaeab"
        var re = str.count1("ab")
        console.log(re) 

        //方法二
        var str = 'abcabca';
        var arr = [];
        var n = 0;
        while (str.indexOf('ab', n) != -1 && n < str.length) {
            arr.push(str.indexOf('ab', n));
            n = str.indexOf('ab', n) + 2;
        }
        var repeatCount = arr.length
        var repeatIndex = arr
        console.log(repeatCount, repeatIndex);

        //方法三
        String.prototype.repeatCount = function (a) { 
            var count = 0
            var index = this.indexOf(a)
            while (index != -1) {
                index = this.indexOf(a, index + 1)
                count++
            }
            return count
        }
        var str = "abcdqwaeab"
        var re = str.repeatCount("ab")
        console.log(re)

4、去掉头尾和全部的空格


        //方法一:去除两端空格
        var str = "    he   llo ";
        console.log(str.trim()); //hello

        //方法二:去除所有空格   !!!!
        console.log(str.replace(/\s*/g, "")); //hello

        //方法三:去除两端空格
        String.prototype.mytrim = function () {
            var a = /\s+/
            var str = this.replace(a, "")
            var b = /\s+$/
            var str = str.replace(b, "")
            return str
        }
        var str = "  hello  "
        var re = str.mytrim()
        console.log(re)


        //方法四:去除两端空格
        String.prototype.mytrim = function (str) {
            var arr = this.split(" ")
            for (var i = 0; i < arr.length; i++) {
                if (arr[i] != "") {
                    return arr[i]
                }
            }
        }
        var str = "   hel   lo  "
        var re = str.mytrim()
        console.log(re)


        //`方法五:(强烈推荐)全部去除`
        var str = '  abc d e f  g ';
        function trimAll(ele) {
            if (typeof ele === 'string') {
                return ele.split(' ').join('');
            } else {
                console.error(`${typeof ele} is not the expected type, but the string type is expected`)
            }
        }
        console.log(trimAll(str))//abcdefg

        //方法六:指定位置清楚空格(第二个参数控制位置)`
        function deleSpac(str, direction) { // 1 串的模板 2 清除哪边空格
            if (typeof str !== 'string') { // 限制下条件,必须是字符串
                console.error(`${typeof ele} is not the expected type, but the string type is expected`)
                return false
            }
            let Reg = '';
            switch (direction) {
                case 'left': // 去除左边
                    Reg = /^[\s]+/g;
                    break;
                case 'right': // 去除右边
                    Reg = /([\s]*)$/g;
                    break;
                case 'both': // 去除两边
                    Reg = /(^\s*)|(\s*$)/g
                    break;
                default:   // 没传默认全部,且为下去除中间空格做铺垫
                    Reg = /[\s]+/g;
                    break;
            }
            let newStr = str.replace(Reg, '');
            if (direction == 'middle') {
                let RegLeft = str.match(/(^\s*)/g)[0]; // 保存右边空格
                let RegRight = str.match(/(\s*$)/g)[0]; // 保存左边空格
                newStr = RegLeft + newStr + RegRight; // 将空格加给清完全部空格后的字符串
            }
            return newStr;
        }
        var str = '  abc d e f  g ';
        console.log(11,deleSpac(str),22)  //abcdefg

5、

var str="abacac"

var re=str.mytool()   //[{key:"a",value:3},3,1,3,2,3,2]

    String.prototype.mytool = function (str) {
            var arr = this.split("")
            var arr1 = []
            var obj = {}
            for (var j = 0; j <= arr.length - 1; j++) {
                for (var i = j + 1, count = 1; i <= arr.length - 1; i++) {
                    if (arr[j] == arr[i]) {
                        arr.splice(i, 1);
                        count++
                    }
                }
                arr[j] = count
                obj["key"] = arr[j]
                obj["value"] = count
                console.log(obj)
            }
            console.log(arr1)
        }
        var str = "abcac"
        var re = str.mytool()

6、第一个字母变大写

 String.prototype.capUppserCase = function () {
            var re = this[0].toUpperCase()
            for (var i = 1; i < this.length; i++) {
                re += this[i]
            }
            return re
        }
        var str = "poStasdasdf"
        var re = str.capUppserCase()
        console.log(re)

7、设计myforEach

 
		var arr = [10, 203, 44]
		Array.prototype.myforEach = function (callback) {
			for (var i = 0; i < this.length; i++) {
				callback(this[i])
			}
		}
		var re = arr.myforEach(function (el) {
			console.log(el)   //10 203 44
		})

8、设计mysome


		Array.prototype.mysome=function(callback) {
			for(var i=0;i<this.length;i++){
				if(callback(this[i],i,this)){return true}
			}
			return false				
		}			
		var  arr=[10,200,500,400]
		var re=arr.mysome(function(el){
			console.log(el)
			return el>100
		})
		console.log(re)

9、判断自循环重复次数或者是否存在 (是否存在:indexOf和match两种方法)

        var str="helloabxh"
        var reg=/lo/
        // var re=str.indexOf("lo")
        var re=str.match(reg)
        console.log(re)
 
        //重复次数--indexOf
        var str="helloabc"
        var count=0
        var temp=0
        while(str.indexOf("lo",temp)!=-1){
            count++
            temp=str.indexOf("lo",temp)+1
        }
        console.log(count)  //1
 
        //重复次数--方法二正则表达式--match
        var str="helloalbxh"
        var reg=/l/g
        var re=str.match(reg)
        console.log(re.length)  //3
 

10、编写一段程序代码,获取今天的日期,格式如“2021-01-01”;并计算下一周同一天的日期。

       var d = new Date();   //获取今天的日期
        var today = d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate();   //将今天的日期改为2021-01-01这种格式
        d.setTime(d.getTime() + 7 * 24 * 3600 * 1000);     
        //d.getTime()将今天的日期转为毫秒 。7 * 24 * 3600 * 1000代表7天时间的毫秒
        // d.setTime(毫秒数)  将d7天后的的日期设置为
        var nexttoday = d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate();  //设置样式
        alert(nexttoday);

11、修改以下代码,使其按照意图输出0,1,2,3,4

// 方法一:
        for (let i = 0; i < 5; i++) {
            setTimeout(function () {
                console.log(i);
            }, i * 1000)
        }

        // 方法二:
        for (let i = 0; i < 5; i++) {
            (
            function (i) {
                setTimeout(function () {
                    console.log(i);
                }, i * 1000)
            })(i)
        }

        // 方法三:
        for (let i = 0; i < 5; i++) {
            setTimeout(function (i) {
                return function () {
                    console.log(i);
                }
            }(i), i * 1000)
        }

12、下面代码输出的内容是

let s=new Set();

s.add([1]);

s.add([1]);

console.log(s.size);

答:2

13、使用es6 合并两个对象

let hebing = {...obj1,...obj2}

14、 下面输出内容是

  Promise.resolve().then(() => {
            return new Error("error!!!")
        }).then((res) => {
            console.log("then:", res)
        }).catch((err) => {
            console.log("catch:", err)
        })

     答:then: Error: error!!!

        解释:.then 或者 .catch 中 return 一个 error 对象并不会抛出错误,所以不会被后续的 .catch 捕获,需要改成其中一种:

        return Promise.reject(new Error('error!!!'))

        throw new Error('error!!!')

        因为返回任意一个非 promise 的值都会被包裹成 promise 对象,即 return new Error('error!!!') 等价于 return Promise.resolve(new Error('error!!!'))。

   

15、获取input框中的value值

在<input name=’pwd’  type=’text’ value=’123’/>和

<input id=’name’type=’text’ value=’zhangsan’>中,我们怎么获取这个两个元素的value值。

Name、type 、id

答 : document.getElementsByName(‘pwd’)[0].value

        document.getElementById(‘name’).value

16、封装一个方法,实现原生JS兼容各类浏览器的元素事件绑定?

function addEvent (el, ename, fn) {
    if(el.addEventListener){
        el.addEventListener(ename, fn);
    } else if (el. attachEvent) {
        el.attachEvent('on' + ename, fn);
    } else {
        // 一定要用中括号,里面支持表达式
        el['on'+ename] = fn;
    }
}

17、数组去重--11种方法

笔试题/面试题——数组去重--9种方法_爱喝牛奶~的博客-CSDN博客

18、深拷贝

1、递归递归去复制所有层级属性;

2、用JSON对象的parse和stringify实现;

JSON.parse(JSON.stringify(obj));

3、借用JQ的extend方法。

方法1. 最简单的方式,缺陷是原型链没有拷贝 函数和null不会拷贝

var copy1 = function (obj) {
        return JSON.parse(JSON.stringify(obj));
    }
    var a = { a: function () { console.log('hello world') }, b: { c: 1 }, c: [1, 2, 3], d: "wanger", e: new Date(), f: null, g: undefined }
    var b = copy1(a)
    return (
        <div>
            <p>{data}</p>
            <button onClick={fn}>点击</button>

        </div>
    )

方法2.利用自调用

export default function App() {
  var copy1 = function (obj) {
    if (obj === null) return null
    if (typeof obj !== 'object') return obj;
    if (obj.constructor === Date) return new Date(obj);
    if (obj.constructor === RegExp) return new RegExp(obj);
    var newObj = new obj.constructor();  //保持继承链
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) {   //不遍历其原型链上的属性
        var val = obj[key];
        newObj[key] = typeof val === 'object' ? arguments.callee(val) : val; // 使用arguments.callee解除与函数名的耦合
      }
    }
    return newObj;
  };

19、防抖节流

//防抖:在第一次触发事件时,不立即执行函数,而是给出一个限定值,比如200ms,然后:
//如果在200ms内没有再次触发事件,那么执行函数
//如果在200ms内再次触发函数,那么当前的计时取消,重新开始计时

//基础版
function debounce(fn, delay) {
    var timer = null;
    return function () {
        if (timer) clearTimeout(timer);
        timer = setTimeout(function () {
            fn();
        },delay)
    }
}

//优化版
function debounce(fn, delay) {
  var timer = null;
  return function() {
    if (timer) clearTimeout(timer);
    // 获取this和argument
    var _this = this;
    var _arguments = arguments;
    timer = setTimeout(function() {
      // 在执行时,通过apply来使用_this和_arguments
      fn.apply(_this, _arguments);
    }, delay);
  }
}
//节流:
//如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效

//基础版
    function throttle(fn, interval) {
        var last = 0;
        return function () {
            // this和arugments
            var _this = this;
            var _arguments = arguments;
            var now = new Date().getTime();
            if (now - last > interval) {
                fn.apply(_this, _arguments);
                last = now;
            }
        }
    }
//优化版
    function throttle(fn, interval) {
        var last = 0;
        var timer = null; // 记录定时器是否已经开启
        return function () {
            // this和arguments;
            var _this = this;
            var _arguments = _arguments;
            var now = new Date().getTime();
            if (now - last > interval) {
                if (timer) { //若已经开启,则不需要开启另外一个定时器了
                    clearTimeout(timer);
                    timer = null;
                }
                fn.apply(_this, _arguments);
                last = now;
            } else if (timer === null) { // 没有立即执行的情况下,就会开启定时器
                //只是最后一次开启
                timer = setTimeout(function () {
                    timer = null; // 如果定时器最后执行了,那么timer需要赋值为null
                    fn.apply(_this, _arguments);
                },interval)
            }
        }
    }

20、判断素数 + `求1到100以内素数`

` 验证一个数字是不是素数/质数`
function primeNum(nub) {
    let n = parseInt(nub);
    // 声明变量num,初始值为true
    let isPrime = true;
    /* for循环里面的 i 变量初始值从2开始,去掉了可以整除的 1,把等号删掉,
    	可以去除它本身*/
    for(let i = 2; i < n; i++) {
        if(n % i == 0) {
        	/*走到这里,说明这个整数除了1和他本身之外,还可以被其他数整除,
        		isPrime变为false,同时终止循环*/ 
            isPrime = false;
            break;
        }
    }
    if(!isPrime) {
        console.log(n + ' 是合数')
    } else {
        console.log(n + ' 是质数')
    }
}
primeNum(7)

`求1到100以内素数`
for (var i=2;i<=100;i++) {
    //假设i是质数,
    var b=true;
    //求证的过程,在1到i之间有没有能被整数整除的数
    for (var j=2;j<i;j++) {
        if(i%j==0){
            //有数被整除了,就证明这个数不是质数
            b=false;
            break;
        }
    }
    if(b==true){
        document.write(i+"<br />")
    }
}

21、判断是否平年闰年

var year = parseInt(prompt('请输入你的年份:'));
if ((year % 4 == 0 && !(year % 100 == 0)) || year % 400 == 0) {
    alert('闰年');
} else {
    alert('平年');
}

22、找出字符串中指定字母下标 , 次数

`1、indexOf()查找指定字符串`
const str = 'abcdef';
console.log(str.indexOf('c'));					// 输出:2

`2、search()查找指定字符串`
const str = 'abcdef';
const reg = RegExp(/e/);
console.log(str.search(reg));					// 输出:4

`3、match()查找指定字符串`
const str = 'abcdef';
const reg = RegExp(/d/);
console.log(str.match(reg));

`js查找字符串中某个字符出现的位置和次数`
var str='sabdcpadhja';
var index=str.indexOf('a');
var num=0;
while(index!==-1){
    console.log(index)//打印出a的索引
    num++;//记录出现的次数
    index=str.indexOf('a',index+1); //利用index为索引,从index+1的位置开始找
}
console.log(num);

`统计一个字符串中,出现次数最多的字符,出现了多少次?`
`第一种方法`
var str = "zhaochucishuzuiduodezifu";
var o = {};
for (var i = 0, l = str.length; i < l; i++) {
    // var char = str[i];
    var char = str.charAt(i);
    if (o[char]) { //char就是对象o的一个属性,o[char]是属性值,o[char]控制出现的次数
        o[char]++; //次数加1
    } else {
        o[char] = 1; //若第一次出现,次数记为1
    }
}
console.log(o); //输出的是完整的对象,记录着每一个字符及其出现的次数
//遍历对象,找到出现次数最多的字符和次数
var max = 0;
var maxChar = null;
for (var key in o) {
    if (max < o[key]) {
        max = o[key]; //max始终储存次数最大的那个
        maxChar = key; //那么对应的字符就是当前的key
    }
}
console.log("最多的字符是" + maxChar); // 最多的字符是u
console.log("出现的次数是" + max); // 出现的次数是5

`第二种方法`
var testStr = 'zhaochucishuzuiduodezifu';
function fn1(str) {
    var strArr = str.split(''); // 把字符串分割成字符串数组
    var strJson = {};
    var maxLength = 0;//最长的长度
    var value = '';//字符值
    for (var i = 0; i < strArr.length; i++) {
        //没有就创建,每一个不同的字符都用一个数组来存放
        if (!strJson[strArr[i]]) {
            strJson[strArr[i]] = [];
        }
        strJson[strArr[i]].push(strArr[i]);// 把当前下标的值push进数组
    }
    //遍历json找到最长的
    for (var attr in strJson) {
        if (strJson[attr].length > maxLength) { // 经过比较得到最长的数组
            maxLength = strJson[attr].length; // 该数组的长度就是出现的次数
            value = attr;
        }
    }
    return '字符最多的是' + value + ',出现了' + maxLength + '次';
}
console.log(fn1(testStr)); // 字符最多的是u,出现了5次

23、实现new关键字

如果函数或者方法调用之前带有关键字new,它就当成构造函数调用。

两种写法:

  1. new fn -->创建对象,不传参,new无参;

  2. new fn( ) -->创建对象,然后调用函数,并传参数,new带参。

new关键词后面跟函数,是一个表达式创建对象的运算,整个表达式一定会得到一个对象。

过程:

  1. 创建一个空对象;

  2. 运行构造函数,让内部的this指向创建的对象(用创建的空对象去调用构造函数);

  3. 整个表达式的结果 ,看函数的返回值;

    • 返回值是引用数据,就是返回值;

    • 返回值不是引用数据,那么就是这个运行完毕之后创建的那个对象。

function myNew(con,...args) {
  let obj = {}
  obj.__proto__ = con.prototype
  let res = con.call(obj,...args)
  if(res instanceof Object) {
    return res
  }else {
    return obj
  }
}

24.实现promise关键字

class MPromise {
    static PENDINGSTATUS = 'pending'
    static FULFILLESSTATUS = 'fulfilled'
    static REJECTEDSTATUS = 'rejected'
    constructor(executor) {
        this.PromiseState = MPromise.PENDINGSTATUS;
        this.PromiseResult = null;
        // 存放then 函数中需要执行的 onFulfilled, onRejected 回调函数
        this.resolvedQueue = [];
        this.rejectedQueue = [];
        // resolve 和 reject 执行时 this 的值为 window,需要绑定 this
        executor(this.resolve.bind(this), this.reject.bind(this));
    }
    resolve(res) {
        // console.log('resolve')
        if (this.PromiseState === MPromise.PENDINGSTATUS) {
            // 通过if 判断状态,实现无法再次修改 promise 的状态
            // 异步执行 resolvedQueue 队列中保存的 onFulfilled 函数
            // 开启微队列
            resultHandlerAsync(() => {
                this.PromiseResult = res;
                this.PromiseState = MPromise.FULFILLESSTATUS;
                if (this.resolvedQueue.length) {
                    const cb = this.resolvedQueue.shift();
                    cb(res)
                }
            })
        }
    }
    reject(err) {
        if (this.PromiseState === MPromise.PENDINGSTATUS) {
            // 异步执行 rejectedQueue 队列中保存的 onRejected 函数
            // 开启微队列
            resultHandlerAsync(() => {
                this.PromiseResult = err;
                this.PromiseState = MPromise.REJECTEDSTATUS;
                if (this.rejectedQueue.length) {
                    const cb = this.rejectedQueue.shift();
                    cb(err)
                }
            })
        }
    }
    then(onFulfilled, onRejected) {
        // then 函数用来注册回调函数,将要执行的 onFulfilled, onRejected 回调函数加入到队列中
        onFulfilled = (typeof onFulfilled === 'function') ? onFulfilled : res => res;
        onRejected = (typeof onRejected === 'function') ? onRejected : err => { throw err };
        return new MPromise((resolve, reject) => {
            if (this.PromiseState === MPromise.PENDINGSTATUS) {
                // 改写目的:实现 onFulfilled 返回值,均会传递给下一次的 then 中 onFulfilled的参数
                this.resolvedQueue.push((res) => {
                    try {
                        const result = onFulfilled(res);
                        resolve(result);
                    } catch (err) {
                        reject(err)
                    }

                });
                this.rejectedQueue.push((err) => {
                    try {
                        const result = onRejected(err);
                        resolve(result);
                    } catch (err) {
                        reject(err)
                    }
                });
            }
        })
    }
    catch(onRejected) {
        return this.then(undefined, onRejected)
    }
    finally(cb) {
        return new MPromise((resolve, reject) => {
            if (this.PromiseState === MPromise.PENDINGSTATUS) {
                // 改写目的:实现 onFulfilled 返回值,均会传递给下一次的 then 中 onFulfilled的参数
                this.resolvedQueue.push((res) => {
                    try {
                        cb()
                        resolve(res);
                    } catch (err) {
                        reject(err)
                    }
                });
                this.rejectedQueue.push((err) => {
                    try {
                        cb();
                        resolve(err);
                    } catch (err) {
                        reject(err)
                    }
                });
            }
        })
    }
    static resolve(res) {
        return new MPromise(resolve => resolve(res))
    }
    static reject(res) {
        return new MPromise((resolve, reject) => reject(res))
    }
    static race(promiseList) {
        return new MPromise((resolve, reject) => {
            promiseList.forEach(p => p.then(res => resolve(res), err => reject(err)))
        })
    }
    static all(promiseList) {
        return new MPromise((resolve, reject) => {
            let promiseArr = [];
            promiseList.forEach(p => {
                p.then(res => {
                    promiseArr.push(res)
                }, err => {
                    throw new Error(err);
                    reject(err);
                })
            })
            resolve(promiseArr);
        })
    }
}

function resultHandlerAsync(cb) {
    // 此函数会开启一个微任务,cb 放入到微任务中执行
    const observer = new MutationObserver(cb);
    observer.observe(document.body, { attributes: true });
    document.body.className = `${Math.random()}`;
}

25、输入一行字符串,由英文字母、数字、和空格组成,并以换行符结尾,其中大写字母、小写字母、数字和空格出现的次数、并依次输出

        var str = "zi fu 9"
        var digital = 0;
        var dcharacter = 0;
        var xcharacter = 0;
        var blank = 0;
        for (var i = 0; i < str.length; i++) {
            if (str.charAt(i) >= "A" && str.charAt(i) <= "Z") {
                dcharacter++
            } else if (str.charAt(i) >= "a" && str.charAt(i) <= "z") {
                xcharacter++
            } else if (str.charAt(i) == " ") {
                blank++
            } else {
                digital++
            }
        }
        console.log(digital, dcharacter, xcharacter, blank)

26、给定N个整数,请你依次输出第一大的数与第一小的数之和,第二大的数与第二小的数之和,第三大的数与第三小的数之和(如果N为奇数,中位数不必输出)

        var n = 5
        var arr = [1, 4, 2, 3, 5]
        var re = arr.sort(function (a, b) {
            return a - b
        })
        var re2 = []
        if (n % 2 == 0) {
            for (var i = 0; i < re.length / 2; i++) {
                re2.push(re[i] + re[re.length - i - 1])
            }
        } else {
            for (var i = 0; i < (re.length / 2) - 1; i++) {
                re2.push(re[i] + re[re.length - i - 1])
            }
        }
        console.log(re2.toString().replace(/,/g, " "))

  • 8
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值