1. call 和 apply 的区别是什么,那个性能更好一些

  1. fn.call(obj, 10, 20, 30);
  2. fn.allpy(obj, [10, 20, 30]);
  3. // call 的性能要比 apply 好一些(尤其是传递给函数的参数超过三个时)所以后期开发的时候,可以使用call 多一点
  4. let arr = [10, 20, 30],
  5. obj = {};
  6. function fn (x, y, z) {}
  7. fn.allpy(obj, arr); // x = 10 y = 20 z = 30
  8. fn.call(obj, arr); // x = [10, 20, 30] y = z = undefined
  9. fn.call(obj, ...arr); // 基于 es6 的展开运算符也可以实现吧数组中的每一项依次传递给函数

2. 自己实现性能测试(仅供参考)

  1. // 任何的代码性能测试都是和测试的环境有关系的,例如 cpu、内存、gpu 等电脑当前性能不会有相同情况,不同浏览器也会导致性能上的不同;
  2. console.time() // 可以测试出一段程序执行的时间
  3. console.profile() // 在火狐浏览器中安装 FireBug,可以更精准的获取到程序每一个步骤所消耗的时间
  4. console.time('A');
  5. for (let i = 0; i < 1000000; i++) {};
  6. console.timeEnd('A');

3. 实现 (5).add(3).minus(2), 使其输出结果为:6

  1. ~ function () {
  2. // 每一个方法执行完,都要返回 number 这个类的实例,这样才可以继续调取 number 类原型中的方法(链式调用)
  3. function check (n) {
  4. n = Number(n);
  5. return isNaN(n) ? 0 : n;
  6. }
  7. function add (n) {
  8. n = check(n);
  9. return this + n;
  10. }
  11. function minus (n) {
  12. n = check(n);
  13. return this - n;
  14. }
  15. Number.prototype.add = add;
  16. Number.prototype.minus = minus;
  17. // ["add", "minus"].forEach (item => {Number.prototype[item] = eval(item)});
  18. }
  19. console.log((5).add(3).minus(2));

4. 箭头函数与普通函数(function 的区别时什么?构造函数(function)可以使用 new 生成实例,那么箭头函数可以吗?为什么?

  1. /**
  2. * 箭头函数和普通函数的区别
  3. * 1. 箭头函数语法上比普通函数更加简洁(es6 中每一种函数都可以使用形参赋默认值和剩余运算符)
  4. * 2. 箭头函数中没有自己的 this,它的 this 时继承函数所处上下文中的 this(使用call / apply 等任何方式都没无法改变 this 的指向
  5. * 3. 箭头函数中没有 arguments(类数组),只能基于 ...arg 获取传递的参数集合(数组)
  6. * 4. 箭头函数不能被 new 执行(因为:箭头函数没有 this 也没有 prototype)
  7. */
  8. function Fn () {
  9. this.x = 100;
  10. }
  11. Fn.prototype.getX = function() {};
  12. let f = new Fn;
  13. let Fn = () => {
  14. this.x = 200;
  15. };
  16. let f = new Fn; // Uncaught TypeError: Fn is not a constructor
  17. // 回调函数:把一个函数 B 作为实参传递给另外一个函数 A,函数 A 在执行的时候,可以把传进来的函数 B 去执行(执行 N 次,可传值,可改 this)
  18. function each (arr, callBack) {
  19. callBack:function(item, index) {
  20. for (let i = 0; i < arr.length; i++);
  21. // 接受回调函数返回的结果,如果时 false,我们结束循环
  22. if (flag === false) {
  23. break;
  24. }
  25. }
  26. }
  27. each([10, 20, 30, 40], function (item, index){
  28. // this:原始操作数组
  29. if (index > 1) {
  30. return false
  31. }
  32. });
  33. let fn = (...arg) => {
  34. // consonle.log(agruments); Uncaught ReferenceRrror:arguments is not defined
  35. console.log(arg);
  36. };
  37. fn(10, 20, 30);

5. 如何把一个字符串大小取反(大写变小写、小写变大写)如:’aBc’ 变成 ‘AbC’

  1. let str = 'zhufengPEIxun的周老师很帅!语*100 HAHAHA';
  2. str = str.replace(/[a-zA-Z]/g, content => {
  3. // content:每一次正则匹配的结果
  4. // 验证是否为大写字母:把字母转换为大写后看和之前是否一样,如果一样,之前也是大写的;在 ascll 表中找到大写字母的取值范围进行判断(65-90)
  5. content.toUpperCase() === content;
  6. content.charCodeAt() > 65 && content.charCodeAt() <=90;
  7. return content.toUpperCase() === content ? content.toLowerCase() : content.toUpperCase();
  8. });
  9. console.log(str);
  10. // 实现一个字符串匹配算法,从字符串 S 中,查找是否存在字符串 T ,弱存在返回所在的位置,不存在返回-1 (如果不能基于 indexOf / includes 等内置方法,你会如何处理
  11. ~ function () {
  12. /**
  13. * 循环原始字符串中的每一项,让每一项从当前位置向后截取 T.length 个字符,然后和 T 进行比较,如果不
  14. 一样,继续循环,如果一样返回当前索引即可(循环结束)
  15. */
  16. function myIndexOf (T) {
  17. // this:S
  18. let lenT = T.length,
  19. lenS = this.length,
  20. res = -1;
  21. if (lenT > lenS) return -1;
  22. for (let i = 0; i <= lenS - lenT; i++) {
  23. if (this.substr(i, lenT) === T) {
  24. res = i;
  25. break;
  26. }
  27. }
  28. return res;
  29. }
  30. // 正则处理
  31. function myIndexOf (T) {
  32. // this:S
  33. let reg = new RegExp(T),
  34. res = reg.exec(this);
  35. return res === null ? -1 : res.index;
  36. }
  37. String.prototype.myIndexOf = myIndexOf();
  38. }();
  39. let S = "zhufengpeixun",
  40. T = "pei";
  41. console.log(S.myIndexOf(T));
  42. // 对象的属性名不能是一个对象(遇到对象属性名,会默认转换为字符串)
  43. // 普通对象 .toStrong() 调取的是 Objcet.prototype 上的方法(这个方法是用来检测数据类型的)
  44. obj = {} // obj.toString() [object object]
  45. obj[b] = 'b' // obj['[object object]] = 'b'

6. 在输入框中如何判断输入的是一个正确的网址,例如:用户输入一个字符串,验证是否符和url网址的格式

  1. let str = "https://www.zhufengpeixun.com.cn";
  2. let reg = /^(?:(http|https|ftp):\/\/)?((?:[\w-]+\.)+[a-z0-9]+)((?:\/[^/?#]*)+)?(\?[^#]+)?(#.+)?$/i;
  3. console.log(reg.exec(str));
  4. /**
  5. * url格式
  6. * 1. 协议:// http / https / ftp
  7. * 2. 域名
  8. * www.zhufengpeixun.cn
  9. * zhufengpeixun.cn
  10. * kbs.sports.qq.com
  11. * kbs.sports.qq.com.cn
  12. * 3. 请求路径
  13. * /
  14. * /index.html
  15. * /str/index.html
  16. * /stu/
  17. * 4. 问号传参
  18. * ?xxx=xxx&xxx=xxx
  19. * 5. 哈希值
  20. * #xxx
  21. */

7. 正则题

  1. /* 编写一条正则,用来验证此规则:一个6~16位的字符串,必须同时包含有大小写字母和数字 */
  2. let reg = /(?!^[a-zA-Z]+$)(?!^[0-9]+$)(?!^[a-z0-9]+$)(?!^[A-Z0-9]+$)^[a-zA-Z0-9]{6,16}$/;
  3. /* 1-10位:数字、字母、下划线组成字符串,必须有_ */
  4. let reg = /(?!^[a-zA-Z0-9]+$)^\w{1,10}$/;
  5. /* 字符串中包含 “\w”,但是必须包含_ */
  6. let reg = /(?=_)\w+/;

8. 实现一个$attr(name,value)遍历

  1. // 属性为name
  2. // 值为value的元素集合
  3. // 例如下面示例:
  4. function $attr(property, value) {
  5. // 获取当前页面中所有的标签
  6. let elements = document.getElementsByTagName('*'),
  7. arr = [];
  8. // [].forEach.call(elements, item => {});
  9. elements = Array.from(elements); // 把非数组转换为数组
  10. elements.forEach(item => {
  11. // 存储的是当前元素 PROPERTY 对应的属性值
  12. let itemValue = item.getAttribute(property);
  13. if (property === 'class') {
  14. // 样式类属性名要特殊的处理
  15. new RegExp("\\b" + value + "\\b").test(itemValue) ? arr.push(item) : null;
  16. return;
  17. }
  18. if (itemValue === value) {
  19. // 获取的值和传递的值校验成功:当前就是我们想要的
  20. arr.push(item);
  21. }
  22. });
  23. return arr;
  24. }
  25. console.log($attr('class', 'box')); */

9. 英文字母汉字组成的字符串,用正则给英文单词前后加空格 */

  1. let str = "no作no死,你能你can,不能no哔哔!",
  2. reg = /\b[a-z]+\b/ig;
  3. str = str.replace(reg, value => {
  4. return " " + value + " ";
  5. }).trim();// String.prototype.trim/.trimLeft/.trimRight 去除字符串首尾空格
  6. console.log(str);

10. 编写一个程序,将数组扁平化,并去除其中重复部分数据,最终得到一个升序且不重复的数组

  1. let arr = [
  2. [1, 2, 2],
  3. [3, 4, 5, 5],
  4. [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10
  5. ];
  6. // 使用ES6中提供的 Array.prototype.flat 处理
  7. arr = arr.flat(Infinity);
  8. // 把数组直接变为字符串即可(数组 TOSTRING之后,不管你有多少级,最后都会变为以逗号分隔的字符串,没有中
  9. 括号和所谓的层级了),相当于直接的扁平化了
  10. arr = arr.toString().split(',').map(item => {
  11. return Number(item);
  12. });
  13. // JSON.stringify 也可以扁平化数组
  14. JSON.stringify(arr) : "[[1,2,2],[3,4,5,5],[6,7,8,9,..."
  15. replace(/(\[|\])/g, '') : "1,2,2,3,4,5,5,6,7,8,9..."
  16. arr = JSON.stringify(arr).replace(/(\[|\])/g, '').split(',').map(item => Number(item));