[关闭]
@gpzjyw 2016-08-24T02:12:43.000000Z 字数 7484 阅读 319

JavaScript Code

JavaScript Interview Front-End


模块或功能实现思路

如何设计一个前端UI组件

参考Bootstrap中的组件设计。

创建一个轮播图

JavaScript动画,设置定时器修改css样式实现。

实现双向数据绑定

参考博客

参考 MVVM 框架的实现

图片懒加载(延迟加载)

参考博客

预加载

手写代码

用JavaScript写一个简单的类

  1. //定义构造函数,定义实例的私有属性
  2. function Person(name, age, sex) {
  3. this.name = name;
  4. this.age = age;
  5. this.sex = sex;
  6. }
  7. //修改(或指定)构造函数的原型对象,定义所有实例的共有方法或属性
  8. Person.prototype.show = function() {
  9. console.log('name:' + this.name);
  10. console.log('age:' + this.age);
  11. console.log('sex:' + this.sex);
  12. };

提供一套运用JavaScript实现类式继承的解决方案

实现事件模型

  1. var eventModel = (function () {
  2. var eventArray = [];
  3. return {
  4. bind: function (func) {
  5. eventArray.push(func);
  6. },
  7. trigger: function () {
  8. for(var i = eventArray.length; i>0; i--){
  9. eventArray.shift()();
  10. }
  11. }
  12. }
  13. })();

实现自定义事件

  1. function EventTarget () {
  2. this.handlers = {};
  3. }
  4. EventTarget.prototype = {
  5. constructor: EventTarget,
  6. addHandler: function (type, handler) {
  7. if (typeof this.handlers[type] == "undefined") {
  8. this.handlers[type] = [];
  9. }
  10. this.handlers[type].push(handler);
  11. },
  12. fire: function (event) {
  13. if (!event.target) {
  14. event.target = this;
  15. }
  16. if (this.handlers[event.type] instanceof Array) {
  17. var handlers = this.handlers[event.type;
  18. for (var i=0, len=handlers.length; i < len; i++) {
  19. handlers[i](event);
  20. }
  21. }
  22. },
  23. removeHandler: function (type, handler) {
  24. if (this.handlers[type] instanceof Array) {
  25. var handlers = this.handlers[type];
  26. for (var i=0, len=handlers.length; i < len; i++) {
  27. if (handlers[i] === handler) {
  28. break;
  29. }
  30. }
  31. handlers.splice(i, 1);
  32. }
  33. }
  34. };

Object.create()

创建一个拥有指定原型的对象(实例)。

  1. if (typeof Object.create !== 'function') {
  2. Object.create = function (o) {
  3. var F = function () {};
  4. F.prototype = o;
  5. return new F();
  6. };
  7. }

创建一个拥有指定原型和若干个指定属性的对象,MDN

  1. if (typeof Object.create != 'function') {
  2. // Production steps of ECMA-262, Edition 5, 15.2.3.5
  3. // Reference: http://es5.github.io/#x15.2.3.5
  4. Object.create = (function() {
  5. //为了节省内存,使用一个共享的构造器
  6. function Temp() {}
  7. // 使用 Object.prototype.hasOwnProperty 更安全的引用
  8. var hasOwn = Object.prototype.hasOwnProperty;
  9. return function (O) {
  10. // 1. 如果 O 不是 Object 或 null,抛出一个 TypeError 异常。
  11. if (typeof O != 'object') {
  12. throw TypeError('Object prototype may only be an Object or null');
  13. }
  14. // 2. 使创建的一个新的对象为 obj ,就和通过
  15. // new Object() 表达式创建一个新对象一样,
  16. // Object是标准内置的构造器名
  17. // 3. 设置 obj 的内部属性 [[Prototype]] 为 O。
  18. Temp.prototype = O;
  19. var obj = new Temp();
  20. Temp.prototype = null; // 不要保持一个 O 的杂散引用(a stray reference)...
  21. // 4. 如果存在参数 Properties ,而不是 undefined ,
  22. // 那么就把参数的自身属性添加到 obj 上,就像调用
  23. // 携带obj ,Properties两个参数的标准内置函数
  24. // Object.defineProperties() 一样。
  25. if (arguments.length > 1) {
  26. // Object.defineProperties does ToObject on its first argument.
  27. var Properties = Object(arguments[1]);
  28. for (var prop in Properties) {
  29. if (hasOwn.call(Properties, prop)) {
  30. obj[prop] = Properties[prop];
  31. }
  32. }
  33. }
  34. // 5. 返回 obj
  35. return obj;
  36. };
  37. })();
  38. }

复制一个对象(深拷贝)

JavaScript 深拷贝

  1. var clone = function (source) {
  2. var o, i;
  3. if (typeof source == "object") {
  4. if (source === null) {
  5. o = null;
  6. } else {
  7. if (source instanceof Array) {
  8. o = [];
  9. for (i=0; i<source.length; i++) {
  10. o[i] = (typeof source[i] == "object")? clone(source[i]) : source[i];
  11. }
  12. } else {
  13. o = {};
  14. for (i in source) {
  15. o[i] = (typeof source[i] == "object")? clone(source[i]) : source[i];
  16. }
  17. }
  18. }
  19. }
  20. return o;
  21. }

jQuery的extend实现深拷贝:newObj = $.extend(true, {}, oldObj)
对于数组对象(Array),可使用Array.slice(0)或Array.concat([])方法;若其中属性值为对象,则对象仍为浅拷贝

Function.prototype.bind函数

简单实现:

  1. if (!Function.prototype.bind) {
  2. Function.prototype.bind = function (obj) {
  3. var _self = this,
  4. args = Array.prototype.slice.call(arguments, 1);
  5. return function () {
  6. return _self.apply(obj, args.concat(Array.prototype.slice.call(arguments)));
  7. }
  8. };
  9. }

MDN Polyfill

  1. if (!Function.prototype.bind) {
  2. Function.prototype.bind = function (oThis) {
  3. if (typeof this !== "function") {
  4. // closest thing possible to the ECMAScript 5
  5. // internal IsCallable function
  6. throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
  7. }
  8. var aArgs = Array.prototype.slice.call(arguments, 1),
  9. fToBind = this,
  10. fNOP = function () {},
  11. fBound = function () {
  12. return fToBind.apply(this instanceof fNOP
  13. ? this
  14. : oThis || this,
  15. aArgs.concat(Array.prototype.slice.call(arguments)));
  16. };
  17. fNOP.prototype = this.prototype;
  18. fBound.prototype = new fNOP();
  19. return fBound;
  20. };
  21. }

跨浏览器事件相关函数

  1. //添加事件
  2. addHandler = function (element, type, handler) {
  3. if (element.addEventListener) {
  4. element.addEventListener(type, handler, false);
  5. } else if (element.attachEvent) {
  6. element.attachEvent("on" + type, handler);
  7. } else {
  8. element["on" + type] = handler;
  9. }
  10. }
  11. //移除事件
  12. removeHandler = function (element, type, handler) {
  13. if (element.removeEventListener) {
  14. element.removeEventListener(type, handler, false);
  15. } else if (element.detachEvent) {
  16. element.detachEvent("on" + type, handler);
  17. } else {
  18. element["on" + type] = null;
  19. }
  20. };
  21. //获取事件对象
  22. getEvent = function (event) {
  23. return event ? event : window.event;
  24. };
  25. //获取事件的真正目标
  26. getTarget = function (event) {
  27. return event.target || event.srcElement;
  28. }
  29. //阻止事件默认行为
  30. preventDefault = function (event) {
  31. if (event.preventDefault) {
  32. event.preventDefault();
  33. } else {
  34. event.returnValue = false;
  35. }
  36. };
  37. //阻止进一步捕获或冒泡
  38. stopPropagation = function (event) {
  39. if (event.stopPropagation) {
  40. event.stopPropagation();
  41. } else {
  42. event.cancelBubble = true;
  43. }
  44. }

Promise对象

jQuery中的Deferred对象

ES6中的Promise

数据结构与算法

二叉查找树

  1. //Node类
  2. function Node(data, left, right){
  3. this.data = data;
  4. this.left = left;
  5. this.right = right;
  6. this.show = functon(){
  7. return this.data;
  8. }
  9. }
  10. //BST类
  11. function BST(){
  12. this.root = null;
  13. //插入
  14. this.insert = insert;
  15. //中序、先序、后序遍历
  16. this.inOrder = inOrder;
  17. this.preOrder = preOrder;
  18. this.postOrder = postOrder;
  19. //查找最小、最大、给定值
  20. this.getMin = getMin;
  21. this.getMax = getMax;
  22. this.find = find;
  23. //删除节点
  24. this.
  25. }
  26. //插入节点到树中
  27. function insert(data){
  28. var n = new Node(data, null, null);
  29. if(this.root == null){
  30. this.root = n;
  31. } else {
  32. var current = this.root;
  33. var parent;
  34. while(true){
  35. parent = current;
  36. if(data < current.data){
  37. current = current.left;
  38. if(current == null){
  39. parent.left = n;
  40. break;
  41. }
  42. } else {
  43. current = current.right;
  44. if(current == null){
  45. parent.right = n;
  46. break;
  47. }
  48. }
  49. }
  50. }
  51. }
  52. //中序遍历
  53. function inOrder(node){
  54. if(!(node == null)){
  55. inOrder(node.left);
  56. node.show();
  57. inOrder(node.right);
  58. }
  59. }
  60. //先序遍历
  61. function preOrder(node){
  62. if(!(node == null)){
  63. node.show();
  64. preOrder(node.left);
  65. preOrder(node.right);
  66. }
  67. }
  68. //后序遍历
  69. function postOrder(node){
  70. if(!(node == null)){
  71. postOrder(node.left);
  72. postOrder(node.right);
  73. node.show();
  74. }
  75. }
  76. //查找最小值
  77. function getMin(){
  78. var current = this.root;
  79. while(!(current.left == null)){
  80. current = current.left;
  81. }
  82. current.show();
  83. }
  84. //查找最大值
  85. function getMax(){
  86. var current = this.root;
  87. while(!(current.right == null)){
  88. current = current.right;
  89. }
  90. current.show();
  91. }
  92. //查找给定值
  93. function find(data){
  94. var current = this.root;
  95. while(current != null){
  96. if(current.data == data){
  97. return current;
  98. } else if(data < current.data){
  99. current = current.left;
  100. } else if(data > current.data){
  101. current = current.right;
  102. }
  103. }
  104. return false;
  105. }

常用正则

匹配中文字符的正则表达式: [\u4e00-\u9fa5]

匹配双字节字符(包括汉字在内):[^\x00-\xff]

匹配空白行的正则表达式:\n\s*\r
ps:可以用来删除空白行

匹配HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? />

匹配首尾空白字符的正则表达式:^\s*|\s*$
ps:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式

匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
ps:表单验证时很实用

匹配网址URL的正则表达式:[a-zA-z]+://[^\s]*

匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
ps:表单验证时很实用

匹配国内电话号码:\d{3}-\d{8}|\d{4}-\d{7}
ps:匹配形式如 0511-4405222 或 021-87888822

匹配腾讯QQ号:[1-9][0-9]{4,}
ps:腾讯QQ号从10000开始

匹配中国邮政编码:[1-9]\d{5}(?!\d)
ps:中国邮政编码为6位数字

匹配身份证:\d{15}|\d{18}
ps:中国的身份证为15位或18位

匹配ip地址:\d+\.\d+\.\d+\.\d+
ps:提取ip地址时有用

匹配特定字符串
1. ^[A-Za-z]+$  //匹配由26个英文字母组成的字符串
2. ^[A-Z]+$  //匹配由26个英文字母的大写组成的字符串
3. ^[a-z]+$  //匹配由26个英文字母的小写组成的字符串
4. ^[A-Za-z0-9]+$  //匹配由数字和26个英文字母组成的字符串
5. ^\w+$   //匹配由数字、26个英文字母或者下划线组成的字符串

匹配特定数字
1. ^[1-9]\d*$    //匹配正整数
2. -[1-9]\d*$   //匹配负整数
3. -?[1-9]\d*$   //匹配整数
4. [1-9]\d*|0$  //匹配非负整数(正整数 + 0)
5. -[1-9]\d*|0$   //匹配非正整数(负整数 + 0)
6. [1-9]\d*\.\d*|0\.\d*[1-9]\d*$   //匹配正浮点数
7. -([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$  //匹配负浮点数
8. -?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$  //匹配浮点数
9. [1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$   //匹配非负浮点数(正浮点数 + 0)
10. (-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$  //匹配非正浮点数(负浮点数 + 0)

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注