@gpzjyw
2016-08-24T02:12:43.000000Z
字数 7484
阅读 319
JavaScript Interview Front-End
参考Bootstrap中的组件设计。
JavaScript动画,设置定时器修改css样式实现。
document对象添加change事件用作事件代理;input textarea select的value和innerHTML)。参考 MVVM 框架的实现
预加载
//定义构造函数,定义实例的私有属性function Person(name, age, sex) {this.name = name;this.age = age;this.sex = sex;}//修改(或指定)构造函数的原型对象,定义所有实例的共有方法或属性Person.prototype.show = function() {console.log('name:' + this.name);console.log('age:' + this.age);console.log('sex:' + this.sex);};
var eventModel = (function () {var eventArray = [];return {bind: function (func) {eventArray.push(func);},trigger: function () {for(var i = eventArray.length; i>0; i--){eventArray.shift()();}}}})();
function EventTarget () {this.handlers = {};}EventTarget.prototype = {constructor: EventTarget,addHandler: function (type, handler) {if (typeof this.handlers[type] == "undefined") {this.handlers[type] = [];}this.handlers[type].push(handler);},fire: function (event) {if (!event.target) {event.target = this;}if (this.handlers[event.type] instanceof Array) {var handlers = this.handlers[event.type;for (var i=0, len=handlers.length; i < len; i++) {handlers[i](event);}}},removeHandler: function (type, handler) {if (this.handlers[type] instanceof Array) {var handlers = this.handlers[type];for (var i=0, len=handlers.length; i < len; i++) {if (handlers[i] === handler) {break;}}handlers.splice(i, 1);}}};
创建一个拥有指定原型的对象(实例)。
if (typeof Object.create !== 'function') {Object.create = function (o) {var F = function () {};F.prototype = o;return new F();};}
创建一个拥有指定原型和若干个指定属性的对象,MDN
if (typeof Object.create != 'function') {// Production steps of ECMA-262, Edition 5, 15.2.3.5// Reference: http://es5.github.io/#x15.2.3.5Object.create = (function() {//为了节省内存,使用一个共享的构造器function Temp() {}// 使用 Object.prototype.hasOwnProperty 更安全的引用var hasOwn = Object.prototype.hasOwnProperty;return function (O) {// 1. 如果 O 不是 Object 或 null,抛出一个 TypeError 异常。if (typeof O != 'object') {throw TypeError('Object prototype may only be an Object or null');}// 2. 使创建的一个新的对象为 obj ,就和通过// new Object() 表达式创建一个新对象一样,// Object是标准内置的构造器名// 3. 设置 obj 的内部属性 [[Prototype]] 为 O。Temp.prototype = O;var obj = new Temp();Temp.prototype = null; // 不要保持一个 O 的杂散引用(a stray reference)...// 4. 如果存在参数 Properties ,而不是 undefined ,// 那么就把参数的自身属性添加到 obj 上,就像调用// 携带obj ,Properties两个参数的标准内置函数// Object.defineProperties() 一样。if (arguments.length > 1) {// Object.defineProperties does ToObject on its first argument.var Properties = Object(arguments[1]);for (var prop in Properties) {if (hasOwn.call(Properties, prop)) {obj[prop] = Properties[prop];}}}// 5. 返回 objreturn obj;};})();}
var clone = function (source) {var o, i;if (typeof source == "object") {if (source === null) {o = null;} else {if (source instanceof Array) {o = [];for (i=0; i<source.length; i++) {o[i] = (typeof source[i] == "object")? clone(source[i]) : source[i];}} else {o = {};for (i in source) {o[i] = (typeof source[i] == "object")? clone(source[i]) : source[i];}}}}return o;}
jQuery的
extend实现深拷贝:newObj = $.extend(true, {}, oldObj);
对于数组对象(Array),可使用Array.slice(0)或Array.concat([])方法;若其中属性值为对象,则对象仍为浅拷贝
简单实现:
if (!Function.prototype.bind) {Function.prototype.bind = function (obj) {var _self = this,args = Array.prototype.slice.call(arguments, 1);return function () {return _self.apply(obj, args.concat(Array.prototype.slice.call(arguments)));}};}
if (!Function.prototype.bind) {Function.prototype.bind = function (oThis) {if (typeof this !== "function") {// closest thing possible to the ECMAScript 5// internal IsCallable functionthrow new TypeError("Function.prototype.bind - what is trying to be bound is not callable");}var aArgs = Array.prototype.slice.call(arguments, 1),fToBind = this,fNOP = function () {},fBound = function () {return fToBind.apply(this instanceof fNOP? this: oThis || this,aArgs.concat(Array.prototype.slice.call(arguments)));};fNOP.prototype = this.prototype;fBound.prototype = new fNOP();return fBound;};}
//添加事件addHandler = function (element, type, handler) {if (element.addEventListener) {element.addEventListener(type, handler, false);} else if (element.attachEvent) {element.attachEvent("on" + type, handler);} else {element["on" + type] = handler;}}//移除事件removeHandler = function (element, type, handler) {if (element.removeEventListener) {element.removeEventListener(type, handler, false);} else if (element.detachEvent) {element.detachEvent("on" + type, handler);} else {element["on" + type] = null;}};//获取事件对象getEvent = function (event) {return event ? event : window.event;};//获取事件的真正目标getTarget = function (event) {return event.target || event.srcElement;}//阻止事件默认行为preventDefault = function (event) {if (event.preventDefault) {event.preventDefault();} else {event.returnValue = false;}};//阻止进一步捕获或冒泡stopPropagation = function (event) {if (event.stopPropagation) {event.stopPropagation();} else {event.cancelBubble = true;}}
//Node类function Node(data, left, right){this.data = data;this.left = left;this.right = right;this.show = functon(){return this.data;}}//BST类function BST(){this.root = null;//插入this.insert = insert;//中序、先序、后序遍历this.inOrder = inOrder;this.preOrder = preOrder;this.postOrder = postOrder;//查找最小、最大、给定值this.getMin = getMin;this.getMax = getMax;this.find = find;//删除节点this.}//插入节点到树中function insert(data){var n = new Node(data, null, null);if(this.root == null){this.root = n;} else {var current = this.root;var parent;while(true){parent = current;if(data < current.data){current = current.left;if(current == null){parent.left = n;break;}} else {current = current.right;if(current == null){parent.right = n;break;}}}}}//中序遍历function inOrder(node){if(!(node == null)){inOrder(node.left);node.show();inOrder(node.right);}}//先序遍历function preOrder(node){if(!(node == null)){node.show();preOrder(node.left);preOrder(node.right);}}//后序遍历function postOrder(node){if(!(node == null)){postOrder(node.left);postOrder(node.right);node.show();}}//查找最小值function getMin(){var current = this.root;while(!(current.left == null)){current = current.left;}current.show();}//查找最大值function getMax(){var current = this.root;while(!(current.right == null)){current = current.right;}current.show();}//查找给定值function find(data){var current = this.root;while(current != null){if(current.data == data){return current;} else if(data < current.data){current = current.left;} else if(data > current.data){current = current.right;}}return false;}
匹配中文字符的正则表达式: [\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)