欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

前端面试笔试题

最编程 2024-02-29 20:31:03
...

1-实现(5).add(3).minus(6)输出6

(function () {
  function check(n) {
    n = Number(n);
    return isNaN(n) ? 0 : n;
  }
  function add(n) {
    n = check(n);
    return this + n;
  }
  function minus(n) {
    n = check(n);
    return this - n;
  }
  ["add", "minus"].forEach((item) => {
    Number.prototype[item] = eval(item);
  });
})();
console.log((5).add(3).minus(2));

2-自行编写each方法

//

let arr = [10, 20, 30, "aa", 40],
  obj = {};

Array.prototype.each = function (...arg) {
  let arr = [];
  if (arg[1]) {
    for (let i = 0; i < this.length; i++) {
      if (arg[0].call(arg[1], this[i]) == false) {
        break;
      }
      arr.push(arg[0].call(arg[1], this[i]));
    }
  } else {
    for (let i = 0; i < this.length; i++) {
      if (arg[0](this[i]) == false) {
        break;
      }
      arr.push(arg[0](this[i]));
    }
  }
  return arr;
};
arr = arr.each(function (item) {
  if (isNaN(item)) {
    return false;
  }
  return item * 10;
});
console.log(arr); //[ 100, 200, 300 ]

3-将字符串的大小写进行翻转

var str = "哈哈哈hhhLLL";
str = str.replace(/[a-zA-Z]/g, (content) => {
  return content.toUpperCase() === content //如果转换成大写之后等于原先的字符即原先的字符就是大写
    ? content.toLowerCase()
    : content.toUpperCase();
});
console.log(str);

4-编写与indexof功能相同的函数

(function () {
  function myIndexOf(T) {
    // let lenT = T.length,
    //   lenS = this.length,
    //   res = -1;
    //if(lenT<lenS){
    //   for (let i = 0; i <= lenS - lenT; i++) {
    //    if (this.substr(i, lenT) === T) {
    //     res = i;
    //     break;
    //   }
    // }
    //}

    // return res;
    let reg = new RegExp(T);
    res = reg.exec(this);
    return res === null ? -1 : res.index;
  }
  String.prototype.myIndexOf = myIndexOf;
})();

let S = "zzzzsssssaaaaa",
  T = "sa";
console.log(S.myIndexOf(T));

5-对象的属性

var a = {},
  b = { key: "123" },
  c = { key: "456" };

a[b] = "b";
a[c] = "c";
console.log(a); //c
/*
  因为在对象的属性中,对象的属性会自动调用该属性原型上的toString()方法转换为字符串
  而任何 对象.toString=='[object Object]'
*/

var a = {},
  b = Symbol("123"),
  c = Symbol("123");
a[b] = "b";
a[c] = "c";
console.log(a); //b
/* Symbol创建的值是唯一的 */

var a = {},
  b = "123",
  c = 123;
a[b] = "b";
a[c] = "c";
console.log(a); //c
/* 因为在对象的属性中,对象的属性会自动调用该属性原型上的toString()方法转换为字符串
因此在这里 123.toString() == '123'*/

6-对象

function Foo() {
  Foo.a = function () {
    console.log(1);
  };
  this.a = function () {
    console.log(2);
  };
}
//在原型上设置实例共有的属性方法,只有实例才能使用
Foo.prototype.a = function () {
  console.log(3);
};
//把Foo当做普通对象设置私有的属性方法
Foo.a = function () {
  console.log(4);
};
Foo.a(); //4
let obj = new Foo();
obj.a(); //2  //自身有,可以不往构造函数的原型上找
Foo.a(); //1   有了实例才能用实例里面的方法

7-正则验证给单词前后加空格

let str = "no哈哈哈h,ho,好借好还",
  reg = /\b[a-z]+\b/gi;
str = str.replace(reg, (value) => {
  return " " + value + " ";
});
console.log(str);

8-数组扁平化

//数组扁平化并除去其中重复部分数据,最终得到一个升序且不重复的数组
// 1.
let arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, [13, 14, [19, 20]]], 10];
// arr = [...new Set(arr.flat(Infinity).sort((a, b) => a - b))];
//2.
// arr = [
//   ...new Set(
//     arr
//       .toString()
//       .split(",")
//       .map((item) => Number(item))
//       .sort((a, b) => a - b)
//   ),
// ];
// console.log(arr);

// 3.

// arr = [
//   ...new Set(
//     JSON.stringify(arr)
//       .replace(/(\[|\])/g, "")
//       .split(",")
//       .map((item) => Number(item))
//       .sort((a, b) => a - b)
//   ),
// ];
// console.log(arr);

// 4.

// while (arr.some((item) => Array.isArray(item))) {
//   arr = [].concat(...arr);
// }
// console.log(arr);

// 5.

~(function () {
  function myFlat() {
    let result = [],
      fn = (arr) => {
        for (let index = 0; index < arr.length; index++) {
          let item = arr[index];
          if (Array.isArray(item)) {
            fn(item);
            continue;
          } else {
            result.push(item);
          }
        }
      };
    fn(this);
    return result;
  }
  Array.prototype.myFlat = myFlat;
})();
arr = arr.myFlat();
console.log(arr);

9-自写new

/*
  new一个实例的时候发生了什么?

  + 像普通函数执行一样,形成一个私有的作用域
    -形参赋值
    -变量提升
  + 默认创建一个对象,让函数中的this执行这个对象,这个对象就是当前类的一个实例
  + 代码执行
  + 默认把创建的对象返回

*/
function Dog(name) {
  this.name = name;
}
function _new(Fn, ...arg) {
  // 1.
  //创建一个空对象,让他的原型链指向Fn.prototype(作为Fn的一个实例)
  // let obj = {};
  // obj.__proto__ = Fn.prototype;

  // 2.
  let obj = Object.create(Fn.prototype);
  Fn.call(obj, ...arg);
  return obj;
}
Dog.prototype.saHi = function () {
  console.log("hi");
};
let sanmao = _new(Dog, "三毛");
sanmao.saHi();

10-合并数组

let arr1 = ["A1", "A2", "B1", "B2", "C1", "C3", "D1"];
let arr2 = ["A", "B", "C"];
//实现合并后的数组为["A1", "A1","A" ,"B1", "B2","B", "C1", "C2","C", "D1"]

// arr2 = arr2.map((item) => item + "Z");
// arr1 = arr1
//   .concat(arr2)
//   .sort((a, b) => a.localeCompare(b))
//   .map((item) => item.replace("Z", ""));
// console.log(arr1);

let index = null;
for (let i = 0; i < arr2.length; i++) {
  for (let j = 0; j < arr1.length; j++) {
    if (arr1[j].includes(arr2[i])) {
      index = j;
    }
  }
  if (index != null) {
    arr1.splice(index + 1, 0, arr2[i]);
    index = null;
  }
}
console.log(arr1);

11-for和定时器

//由于使用var来定义的变量没有块级作用域。for循环中创建的定时器还没启动,for循环就已经完成,
//此时打印i则是调用全局的i,这时i=10;

/*for (var i = 0; i < 10; i++) {
  setTimeout(() => {
    console.log(i);
  }, 100);
}*/

// 闭包解决
// for (var i = 0; i < 10; i++) {
//   ~(function (i) {
//     setTimeout(() => {
//       console.log(i);
//     }, 1000);
//   })(i);
// }

// for (var i = 0; i < 10; i++) {
//   // ~(function (i) {
//   //   setTimeout(() => {
//   //     console.log(i);
//   //   }, 1000);
//   // })(i);
//   setTimeout(
//     ((i) => {
//       return () => {
//         console.log(i);
//       };
//     })(i),
//     1000
//   );
// }

//使用bind,使用bind的预先处理机制,在循环的时候就把每次执行函数需要输出的结果,预先传递给函数即可
var fn = function (i) {
  console.log(i);
};
for (var i = 0; i < 10; i++) {
  setTimeout(fn.bind(null, i), 1000);
}

12-匿名函数起名字

// let fn = function AAA() {
//   console.log(AAA);
// };
// fn();
// function fn() {
//   console.log(fn);
// }
// console.log(fn);

var b = 10;
(function b() {
  var b = 20;
  console.log(b); //20
})();
console.log(b); //10

var c = 10;
(function c() {
  c = 20;
  console.log(c); //函数c
})();
console.log(c); //10

13-==进行比较时的操作

/*
==进行比较的时候,如果左右两边数据类型不一样,则先转换为相同的数据类型再进行比较
1. {}=={} 对象进行比较,比较的是堆内存的地址
2. null==undefined 相等 null === undefined 不相等
3. NaN和谁都不相等,包括NaN==NaN
4. 其他数据类型和字符串进行比较,把其他类型toString()后和字符串进行比较
5. 剩余所有情况在进行比较的时候都是转换为数字(前提是数据类型不同)
*/
// console.log({} == {});
// console.log(null == undefined);
// console.log(NaN == NaN);
// console.log([1] == "1");
// console.log([1] == true);

// var a = {
//   n: 0,
//   toString() {
//     return ++this.n;
//   },
// };
var a = [1, 2, 3];
a.toString = a.shift; //使其toString方法改变,调用自己的私有方法
if (a == 1 && a == 2 && a == 3) {
  console.log(123);
}

15-push

let obj = {
  2: 3,
  3: 4,
  length: 2,
  push: Array.prototype.push,
};
obj.push(1);
obj.push(2);
console.log(obj);

//首先我们需要知道Array.prototype.push实现的时候进行了什么
/*
  Array.prototype.push = function (val) {
    this[this.length] = val;
    return this.length;
  };
*/
/*
  如此可知在数组push的时候是将 this[this.length] = 新的值,并且这个数组的长度+1;
  所以在这题中,
  let obj = {
  2: 1,
  3: 2,
  length: 4,
  push: Array.prototype.push,
};
*/

16-冒泡排序

/*
  冒泡排序思想: 让数组中的当前项和后一项进行比较,把值较大的放在后面.
  最少要进行length-1轮比较,每轮比较都会把最大,次大,次三大..的值放到后面。

  第一轮最多比较length-1次
  第二轮最多比较length-2次
  第三轮最多比较length-3此
  .....
*/

let arr = [12, 8, 24, 16, 1];

function bubble(arr) {
    // let temp = 0;
    for (let i = 0; i < arr.length - 1; i++) {
        for (let j = 0; j < arr.length - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
            }
        }
    }
    return arr;
}
bubble(arr);

17-插入排序

/*
  插入排序(抓扑克牌的排序)
  首先先抓一张牌,再抓第二张牌,第二张牌和抓到的牌由后到头进行比较,在遇到比它小的牌就插
  在这张牌的后面
   
*/
function insertSort(arr) {
  let array = [];
  array.push(arr[0]);
  for (let i = 1; i < arr.length; i++) {
    for (let j = array.length - 1; j >= 0; j--) {
      if (array[j] <= arr[i]) {
        array.splice(j + 1, 0, arr[i]);
        break;
      }
      if (j === 0) {
        array.unshift(arr[i]);
      }
    }
  }
  console.log(array);

  return array;
}
insertSort([13, 8, 12, 1, 16, 0]);

18-快速排序

/*
arr=[24,8,9,6,15,2];
快速排序则是取中间的值,然后在arr中将该中间值去掉,使剩下的数值与该中间值进行比较

假设中间值是9
比9小的放到左数组,比9大的放到右数组
左数组:[8,6,2]
右数组:[24,15]
然后再对该左右数组取中间值,再分左右数组以此类推,直至剩下最后一个数,再将左右数组与中间数拼接

*/

function quickSort(arr) {
  //4.结束递归,当arr中小于等于一项
  if (arr.length <= 1) {
    return arr;
  }

  //1.找到数组的中间项,在原有的数组中将它移除
  let middleIndex = Math.floor(arr.length / 2);
  let middleValue = arr.splice(middleIndex, 1)[0];

  //2. 准备左右两个数组,循环剩下数组中的每一项
  let left = [],
    right = [];

  for (let i = 0; i < arr.length; i++) {
    arr[i] > middleValue ? right.push(arr[i]) : left.push(arr[i]);
  }
  //3. 递归让左右两边的数组持续这样处理,知道左右两边都排好序位置。(最后让左+中+右)
  return quickSort(left).concat(middleValue, quickSort(right));
}
console.log(quickSort([24, 8, 9, 6, 15, 2]));

19-对象变数组

/*
  某公司1-12月份的销售额如下
  let obj = {
    1: 222,
    2: 123,
    5: 888,
  };

  将其变成如下结构
  [222,123,null,null,888,null,null,null,null,null,null]

*/

let obj = {
  1: 222,
  2: 123,
  5: 888,
};

// 1.
// let arr = new Array(12).fill(null).map((item, index) => {
//   return obj[index + 1] || null;
// });

// 2.
obj.length = 13;
let arr = Array.from(obj).slice(1);
console.log(arr);
arr = arr.map((item) => (item == undefined ? null : item));
console.log(arr);

20-旋转数组

/*
  旋转数组
  给定一个数组,将数组中的元素向右移动k个位置,其中k是非负数
  输入:[1,2,3,4,5,6] k=3
  输出: [5,6,7,1,2,3,4]
*/

function rotate(arr, k) {
  if (k < 0 || k === 0 || k === arr.length) return arr;
  if (k > arr.length) k = k % arr.length;
  // for (let i = 0; i < k; i++) {
  //   arr.unshift(arr.pop());
  // }

  return arr.splice(arr.length - k).concat(arr);
}
console.log(rotate([1, 2, 3, 4, 5, 6, 7], 3));

21-实现add函数

/*
  实现add函数满足以下功能

  add(1);  //1
  add(1)(2);//3
  add(1)(2)(3);//6
  add(1)(2,3);//6
  add(1,2)(3);//6
  add(1,2,3);//6


  函数柯理化:预先处理的思想(利用闭包的机制)
  */
//手写bind
// ~(function () {
//   function myBind(context = window, ...outerArg) {
//     let _this = this;
//     return function (...innerArg) {
//       _this.call(context, ...outerArg.concat(innerArg));
//     };
//   }
//   Function.prototype.myBind = myBind;
// })();
// //利用闭包的保存作用,柯理化预先保存思想
// function fn(x) {
//   return function (y) {
//     return x + y;
//   };
// }

// console.log(fn(100)(200));

function currying(fn, length) {
  length = length || fn.length;
  return function (...arg) {
    if (arg.length >= length) {
      return fn(...arg);
    }
    return currying(fn.bind(null, ...arg), length - arg.length);
  };
}

// add = currying(add, 4);
let add = currying((...arg) => eval(arg.join("+")), 4);

// console.log(add(1));

console.log(add(1)(2)(3)(4));
// console.log(add(1, 2)(3, 4));
// add(1);
// add(1)(2)(3)(4);