JavaScript 实用工具函数与进阶技巧详解
本文整理了JavaScript开发中的常用实战技巧,涵盖Cookie读写封装、对象属性可视化调试、正则表达式基础概念及常用方法,并深入解析了call()与apply()在改变执行上下文、模拟多继承及数组参数优化中的应用。
Cookie 操作工具函数
在实际项目中,经常需要设置和读取Cookie。以下是一个封装好的 CookieTool 函数,支持设置过期时间、路径、域名等选项,以及读取指定名称的Cookie值。
第1步:实现 Cookie 读写功能
- 目的:统一管理Cookie的存储与获取,避免重复编写原生JS代码。
- 入口:直接调用全局函数
CookieTool(name, value, options)。 - 关键逻辑:通过判断
value是否存在来决定是写入还是读取。写入时处理日期转换和URL编码;读取时遍历document.cookie进行匹配。
/**
* cookie操作工具.
* 使用方法:保存值:CookieTool('name','1',{expires: 7}) //表示保存一个cookie值为1,键值为name,失效时间7天以后
* 取值:CookieTool('name') //返回1
*/
CookieTool = function(name, value, options) {
if (typeof value != 'undefined') {
options = options || {};
if (value === null) {
value = '';
options.expires = -1;
}
var expires = '';
if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
var date;
if (typeof options.expires == 'number') {
date = new Date();
date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
} else {
date = options.expires;
}
expires = '; expires=' + date.toUTCString();
}
var path = options.path ? '; path=' + (options.path) : '';
var domain = options.domain ? '; domain=' + (options.domain) : '';
var secure = options.secure ? '; secure' : '';
document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
} else {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
};
对象调试可视化工具
在排查复杂对象结构时,逐个打印属性效率较低。下面的 debugObjectInfo 函数可以将对象的所有属性和值以表格形式在新窗口中展示,便于快速查看。
第2步:使用 debugObjectInfo 调试对象
- 目的:将对象的内部状态以HTML表格形式直观呈现。
- 动作:调用
debugObjectInfo(obj),传入待调试的对象。 - 参数说明:
obj为任意JavaScript对象,函数会自动遍历其所有可枚举属性。 - 完成状态:浏览器弹出一个新窗口(traceWindow),显示包含对象标签名、ID及所有属性列表的表格。
/**
* 用来查看一个对象的属性
*/
function debugObjectInfo(obj){
traceObject(obj);
function traceObject(obj){
var str = '';
if(obj.tagName&&obj.name&&obj.id)
str="<table border='1' width='100%'><tr><td colspan='2' bgcolor='#ffff99'>traceObject tag: <"+obj.tagName+"> name = \""+obj.name+"\" id = \""+obj.id+"\" </td></tr>";
else{
str="<table border='1' width='100%'>";
}
var key=[];
for(var i in obj){
key.push(i);
}
key.sort();
for(var i=0;i<key.length;i++){
var v= new String(obj[key[i]]).replace(/</g,"<").replace(/>/g,">");
str+="<tr><td valign='top'>"+key[i]+"</td><td>"+v+"</td></tr>";
}
str=str+"</table>";
writeMsg(str);
}
function trace(v){
var str="<table border='1' width='100%'><tr><td bgcolor='#ffff99'>";
str+=String(v).replace(/</g,"<").replace(/>/g,">");
str+="</td></tr></table>";
writeMsg(str);
}
function writeMsg(s){
traceWin=window.open("","traceWindow","height=600, width=800,scrollbars=yes");
traceWin.document.write(s);
}
}
正则表达式基础与常用方法
正则表达式是字符串处理的核心工具。理解修饰符和特殊字符序列能显著提升匹配精度。
第3步:掌握常用修饰符与模式元字符
- 修饰符:
g(全局匹配)、m(多行匹配)、i(忽略大小写)。 - 边界与量词:
^(开头)、$(结尾)、*(零次或多次)、+(一次或多次)、?(零次或一次,非贪婪模式时配合限制符使用)。 - 字符类:
\d(数字)、\w(单词字符)、\s(空白字符)、b(单词边界)。
第4步:调用 RegExp 对象的方法
JavaScript 提供了多个正则操作方法,如 match 查找匹配项,search 查找位置,test 验证是否符合,以及 exec 返回详细匹配信息。
/**
* 在源字符串中查找满足要求的子串.
*/
function MatchDemo() {
var r, re;
var s = "The rain in Spain falls mainly in the plain";
re = new RegExp("ain", "g");
r = s.match(re);
return (r);
}
/**
* 对源字符串进行正则表达式检查,看是不是符合正则表达式.
*/
function TestDemo() {
var s1;
var source = "abcdefg";
var regex = /\w+/g;
if (regex.test(source))
s1 = " contains ";
else
s1 = " does not contain ";
return ('"' + source + "'" + s1 + '"' + regex.source + "'");
}
/**
* 在源字符串中查找正则表达式的字串.
*/
function SearchDemo() {
var r, re;
var s = "The rain in Spain falls mainly in the plain.";
re = /falls/i;
r = s.search(re);
return (r);
}
Call 与 Apply 函数的进阶应用
call 和 apply 的主要作用是改变函数内部的 this 指向,从而实现方法借用、继承模拟及参数传递优化。
第5步:使用 Call 实现方法借用与模拟继承
- 目的:让一个对象具备另一个对象的方法,或在构造函数间共享逻辑。
- 语法:
func.call(thisObj, arg1, arg2, ...)。 - 示例场景:
- 简单替换:用
add.call(sub, 3, 1)使sub调用add的逻辑,相当于add(3, 1)。 - 属性借用:子类
Class2通过Class10.call(this)继承Class10的方法,实现多重继承效果。
- 简单替换:用
// 简单例子:用 add 来替换 sub
function add(a,b) { alert(a+b); }
function sub(a,b) { alert(a-b); }
add.call(sub,3,1); // 结果为 alert(4)
// 多重继承例子
function Class10() { this.showSub = function(a,b) { alert(a-b); }; }
function Class11() { this.showAdd = function(a,b) { alert(a+b); }; }
function Class2() {
Class10.call(this);
Class11.call(this);
}
第6步:利用 Apply 优化数组参数传递
- 目的:当函数接受可变数量参数,而参数以数组形式存在时,利用
apply展开数组。 - 语法:
func.apply(thisObj, [argsArray])。 - 典型应用:
- 求最大值:
Math.max.apply(null, arr)可直接求出数组中的最大元素,比循环遍历更高效简洁。 - 合并数组:
Array.prototype.push.apply(arr1, arr2)可将arr2的元素追加到arr1末尾,且原地修改arr1。
- 求最大值:
// 获取数组最大值
function getMax2(arr){
return Math.max.apply(null, arr);
}
// 合并两个数组
var arr1=[1,3,4];
var arr2=[3,4,5];
Array.prototype.push.apply(arr1, arr2);
// 结果 arr1 为 [1,3,4,3,4,5]
第7步:综合示例 - Student 类的多重继承
结合 apply 可以同时从多个父类继承属性。例如 Student 类同时继承自 Person 和 Print 类。
function Person(name,age){
this.name=name;
this.age=age;
this.sayhello=function(){alert("hello")};
}
function Print(){
this.funcName="Print";
this.show=function(){
var msg=[];
for(var key in this){
if(typeof(this[key])!="function"){
msg.push([key,":",this[key]].join(""));
}
}
alert(msg.join(" "));
};
}
function Student(name,age,grade,school){
Person.apply(this,arguments);
Print.apply(this,arguments);
this.grade=grade;
this.school=school;
}
var s1=new Student("tom",13,6,"清华小学");
s1.show(); // 输出: name:tom age:13 funcName:Print grade:6 school:清华小学
s1.sayhello(); // 输出: hello
以上就是JavaScript Cookie操作、对象调试、正则及Call Apply技巧的详细内容,更多关于JavaScript高级特性的资料请关注本站其它相关文章!本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













