这是我参与11月更文挑战的第23天,活动详情查看:2021最后一次更文挑战
除了函数相关的基础知识外,掌握一些高级函数并应用起来,不仅能让JS代码看起来更为精简,还可以提升性能。很多“高级函数”的实现其实并不复杂,数十行代码便可搞定,但重要的是能真正理解它们的原理,在实际中适时地应用。
安全的类型检测
在任何值上调用 Object 原生的 toString() 方法,都会返回一个 [object NativeConstructorName] 格式的字符串。如:
console.log(Object.prototype.toStrig.call(value)); // "[object Array]"
所以,使用 toString() 能保证返回一致的值。更安全的类型检测可以创建如下函数:
function isArray(value) {
return Object.prototype.toString().call(value) == "[object Array]";
}
function isRegExp(value) {
return Object.prototype.toString.call(value) == "[object RegEXP]";
}
作用域安全的构造函数
构造函数是一个使用 new 操作符调用的函数。
function Person(name, age ,job) {
this.name = name;
this.age = age;
this.job = job;
}
var person = new Person("nickname", 20, "teacher");
看似没有问题,但是如果没有使用 new 操作符调用该构造函数时,该 this 对象是在运行时绑定的,直接调用 Person(),this 会映射到 window 上。
解决方法:创建一个作用域安全的构造函数。在进行任何更改前,先确认 this 对象是正确类型的实例,如果不是,创建新的实例并返回。
function Person(name, age, job) {
if (this instanceof Person) {
this.name = name;
this.age = age;
this.job = job;
} else {
return new Person(name, age, job);
}
}
惰性载入函数
惰性载入表示函数执行的分支仅会发生一次。惰性载入方式:
-
函数被调用时再处理函数。在第一次调用时,用另外一个按合适方式执行的函数覆盖该函数。如:
function createXHR() { if (typeof XMLHttpRequest != "undefined") { createXHR = function() { return new XMLHttpRequest(); }; } else if (typeof ActiveXObject != "undefined") { createXHR = function() { ...dosomething }; } else { createXHR = function() { throw new Error("error"); }; } return createXHR(); }if 语句的每一个分支都会为 createXHR 变量赋值,覆盖原有的函数。
-
在声明函数时指定适合的函数。
var createXHR = (function createXHR() { if (typeof XMLHttpRequest != "undefined") { return function() { return new XMLHttpRequest(); }; } else if (typeof ActiveXObject != "undefined") { return function() { ...dosomething }; } else { return function() { throw new Error("error"); }; } })();创建一个匿名、自执行的函数,确定使用哪一个函数实现。
惰性载入函数只在执行分支代码时牺牲一点儿性能。