js中没有class的概念,我们可以使用function来模拟。
惰性载入函数
例如我们通常使用以下的js代码创建ajax:
function createXHR () { var xhr = null; try{ xhr = new XMLHttpRequest(); // FF、Opera、Safari、IE7 } catch(e) { handlerError(e); try{ xhr = new ActiveXObject('Msxml2.XMLHTTP'); } catch (e) { try{ xhr = ActiveXObject('Microsoft.XMLHTTP'); } catch(e) { xhr = null; } } } return xhr; } function handlerError (err) { var errXHR = err; // ... }
在现代的网络技术中ajax技术早已是烂大街了,一个网页通常包含很多的ajax——也就导致了频繁创建xhr从而导致内存泄露。我们可以采用惰性载入函数来动态生成xhr。
/* 惰性函数(第二次生效) */ function createXHR () { var xhr = null; if (typeof XMLHttpRequest != 'undefined') { xhr = new XMLHttpRequest(); createXHR = function () { return new XMLHttpRequest(); } } else { try{ xhr = new ActiveXObject('Msxml2.XMLHTTP'); createXHR = function () { return new ActiveXObject('Msxml2.XMLHTTP'); } } catch (e){ try{ xhr = new ActiveXObject('Microsoft.XMLHTTP'); createXHR = function () { return new ActiveXObject('Microsoft.XMLHTTP'); } } catch (e){ createXHR = function () { return null; } } } } return xhr; }
我们调用以上的方法创建xhr,在运行第二次的时候就不用每次都判断了,直接返回xhr。
函数柯里化
函数的柯里化(curry)把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。,简而言之就是两个函数的参数的合并。例如:
function curry(fn) { var args = Array.prototype.slice.call(arguments,1); // 取curry的参数并将其变为数组[100] console.log(args); // [100] return function () { var innerArgs = Array.prototype.slice.call(arguments); // 匿名函数的参数列表[1,2] console.log(innerArgs); // [1,2] var finalArgs = args.concat(innerArgs); // 合并数组(参数合并) console.log(finalArgs); // [100,1,2] return fn.apply(null, finalArgs); } } function add(num1,num2,num3) { return num1 + num2 + num3; } var t = curry(add,100)(1,2); console.info(t);
级联函数
级联就是一个对象将其所有有关的东西连接到了一起。如:以下的对象。
// 人:手、腿、嘴 function classPerson(){ this.hand = ""; this.foot = ""; this.leg = ""; } classPerson.prototype = { setHand:function(){ this.hand = '大手'; }, setLeg:function () { this.leg = '长腿欧巴'; }, setMouse:function () { this.mouse = '樱桃小嘴'; } } var person = new classPerson(); person.setHand(); person.setMouse(); person.setLeg(); console.log(person);
我们知道造人是一个整体(不可能先造手、再造腿、最后造嘴),我们现在的需求是一旦实例化人这个对象,该有的都有了。
简单修改以上代码:
function classPerson(){ this.hand = ""; this.foot = ""; this.leg = ""; } classPerson.prototype = { setHand:function(){ this.hand = '大手'; return this; }, setLeg:function () { this.leg = '长腿欧巴'; return this; }, setMouse:function () { this.mouse = '樱桃小嘴'; return this; } } var person = new classPerson(); person.setHand().setMouse().setLeg(); // 调用函数 console.log(person);
我们在每个setter中添加了return this将原有对象返回(避免无返回值的函数执行完之后是undefined)。我们可以惊奇的发现常用的JQuery的链式调用就是一种级联调用:
$(‘#id').show().hide().show().hide().show().hide();
javascript中的正则表达式
一般来说//在js中表示的是单行注释,但是一旦我们向斜杠中间加入了内容,例如:/TEST/它就神奇地变成了正则。
模式串的声明
var patt1 = new RegExp('hello'); // 方式一 var patt2 = /word/; // 方式二
test方法
我们得到了模式串(模式对象)后可以调用该方法匹配字符串,返回指定值(true or false)。
var patt = /my/; var str = 'this is my code...'; console.log(patt.test(str)); // true
exec方法
类似于字符串的match方法,但是当模式串指定为全局的时候两者表现不同,没有匹配返回null。
/hello/.exec('oh hello world'); // ["hello"]
以上两个方法都是字符串对象本身的方法,下面的几个方法是字符串中的有关正则的方法。
match方法
模式匹配。函数原型是str.mattch(pattern),将匹配的结果以数组返回。
console.log('test 123'.match(/test/g)); // [test]
replace方法
字符串替换,注意:该方法生成一个新的临时字符串副本。如图所示:
split方法
将字符串拆分成按照模式拆分成数组。
console.log('Hello world,hello everyone'.split(/\s+/)); // ["Hello", "world,hello", "everyone"] console.log('Hello world,hello everyone'.split(' ')); // 等效于上面的方法
正则的类型
/pattern/attributes
attributes是可选字符串,常用的属性是“g”(全局匹配)、“i”(大小写不敏感)和"m"(多行匹配)
console.log('Hello world,hello everyone'.match(/hEllO/gi)); // 全局查找hello并忽略大小写 ["Hello", "hello"]