勿忘初心

实用型JavaScript方法总结--持续更新中

收集一些比较有趣且实(装)用(X)的JavaScript方法实现,学习并提供总结,欢迎大家提提意见一起探讨。

去抖动函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//在一段连续时间内,传入的fn只执行一次
//去抖动函数
function debouce(fn,time,immediate){
var firstCall = false,//没有执行过
timer = null;
return function(){
var delayFn,
ctx = this,
args = arguments;
var callNow = immediate && !firstCall;
if(callNow){
firstCall = true;//执行过
return fn.apply(ctx, args);
}
delayFn = function(){
timer = null;
fn.apply(cxt,args);
}
clearTimeout(timer);
timer = setTimeout(delayFn, time);
}
}

节流函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//节流函数
//在一段连续时间内,减少这段时间内fn的执行频率
function throttle(fn, delay){
var last = 0,
timer;
return function(){
var ctx = this,
res = null,
now = Date.now(),
args = arguments,
remainTime = delay - (now - last);//距离上一次执行的剩余时间
//last为0:代表第一次执行。remainTime<=0:剩余时间为0立刻执行fn。
//remainTime>delay:代表 remainTime - delay = -(now-last) = last-now >0,表示客户端时间调为了过去时间
if(last == 0 || remainTime <=0 || remainTime > delay){
//立刻执行
if(timer){
clearTimeout(timer);
timer = null;
}
now = Date.now();
return fn.apply(ctx, args);
}else{
clearTimeout(timer);
timer = setTimeout(function(){
now = Date.now();
res = fn.apply(ctx, args);
ctx = null;
args = null;
timer = null;
}, remainTime);
return res;
}
}
}

类型判断

1
2
3
4
5
6
//类型判断
function isType(type) {
return function(obj) {
return Object.prototype.toString.call(obj) === '[object ' + type + ']';
}
}

分批执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//集合内元素单位时间内按fn分批执行
function timeChunk (ary, fn, count) {
var obj,t,len = ary.length,trunks = 0,out = false;
var start = function() {
for (var i = trunks * (count || 1); i < len; i++) {
var min = (trunks + 1) * count;
if(i == len -1){
out = true;
}
if (i - min >= 0) {
trunks += 1;
break;
}
fn(ary[i]);
}
}
return function() {
t = setInterval(function() {
if (out) { // 如果全部节点都已经被创建好
return clearInterval(t);
}
start();
}, 2000); // 分批执行的时间间隔,也可以用参数的形式传入
};
};
var a = [1,2,3,4,5,6,7,8,9];
var xfn = function(i){
console.log(i);
}
var count = 5;
var test = timeChunk(a, xfn,count);

装饰器 aop面向切面编程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//aop面向切面编程
Function.prototype.before = function(fn){
var selfFn = this;
return function(){
fn.apply(this,arguments);// 执行新函数,修正this
return selfFn.apply(this,arguments);// 执行原函数
}
}
Function.prototype.after = function(fn){
var selfFn = this;//保存当前函数的引用
return function(){
var res = selfFn.apply(this, arguments)
fn.apply(this, arguments);
return res;
}
}

Object.create的实现原理、new对象的步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//Object.create的实现原理
//object.create一般用来创建obj,其实质就是将源对象的引用指向到实例的__proto__上,var a = {a:1}; var b = Object.create(a); b的结构:{__proto__:{a:1,__proto__{...}}},{a:1,__proto__{...}}就是a
function ObjectCreate(o){
function F(){};
F.prototype = o;
return new F();
}
//new对象的步骤
var objectFactory = function() {
var obj = new Object(); // 从Object.prototype 上克隆一个空的对象
var Constructor = [].shift.call(arguments); // 取得外部传入的构造器,此例是Person
obj.__proto__ = Constructor.prototype; // 指向正确的原型
var ret = Constructor.apply(obj, arguments); // 借用外部传入的构造器给obj 设置属性
return typeof ret === 'object' ? ret : obj; // 确保构造器总是会返回一个对象
};

instanceof的实现原理

1
2
3
4
5
6
7
8
9
function instaceof_(A, B){
var ao = A.__proto__;
var bo = B.prototype;
while(true){
if(ao === null) return false;// 因为Object.prototype.__proto__ 为null
if(ao === bo) return true;
A = A.__proto__;
}
}

判断对象是否为空

1
2
3
4
5
6
7
8
function isEmptyObj(obj){
for(var i in obj){
if(obj.hasOwnproperty(i)){//只针对对象自身属性,而非继承属性
return false;
}
}
return true;
}

蹦床函数

1
2
3
4
5
6
7
8
9
10
11
12
//递归方法优化,防止函数调用栈溢出最大值
//当在函数作用域下 调用另外一个函数 循环往复 会超出函数调用最大值
//这种情况可以采用递归调用来优化,可以用到蹦床函数:接收一个参数,当参数类型为函数时,执行并返回。
//场景:一个方法需要在方法内循环调用,体量很大,则需要使用蹦床函数递归优化。
function trampoline(fn){
while(true){
if(fn && fn instanceof Function){
fn = fn();
}
return fn;
}
}

事件监听的装饰模式

1
2
3
4
5
6
7
8
9
10
11
12
//事件监听的装饰模式
function addEvent(dom, handle, type){
try{
if("addEventListener" in document){
dom.addEventListener(type,handle);
}else{
dom.attachEvent("on"+type,handle);
}
}catch(e){
dom["on"+type] = handle;
}
}

需求实现 add(1)(2)(3) - 6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//需求实现 add(1)(2)(3) - 6
function add(n){
var arr = [];
function fn(){
[].push.apply(arr, [].slice.apply(arguments));
return fn;
}
fn.toString = function(){
var res = 0;
arr.map(function(item, i) {
res+=item;
})
return res;
}
return fn(n)
}

require和define的原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//require和define的模拟
(function(w){
var require,
define;
// factory只调用一次,初始化后下次require的时候不再调用factory方法,
//而是直接返回modules[id].exports这里调用factory是隐式赋值,
//利用对象在函数中作为参数传递时,只是传递的对象的引用,
//那么只要在define方法的factory中module.exports进行属性赋值,
//就相当于直接在modules中修改属性
(function(){
var module = {};
//id只是命名空间,factory在require时执行,export是命名空间的输出
//factory的执行目的就是将这个空间内需要存储的对象放入export中
//在require该命名空间时返回export
define = function(id, factory){
if(!module[id]){
module[id] = {
id: id,
factory: factory,
export: {}
}
}else{
console.log(id+" the module has been define")
}
}
//接收一个id 并返回在define中factory生成的对象
require = function(id){
if(!module[id]){
console.log(id+" the module is not defined");
}else{
if(module[id].factory){
var factory = module[id].factory;
factory(require, module[id].export, module[id]);
delete module[id].factory;
}
return module[id].export;
}
}
define.remove = function(id){
delete module[id];
}
})();
})(window)

继承实现方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function extend(){
return function(child, parent){
function F(){};
F.prototype = parent.prototype;
child.prototype = new F;
child.prototype.constructor = child;
child.subperproto = parent.prototype;
return child;
}
}
var inherit = (function(){
function F() {}
return function (child, parent) {
F.prototype = parent.prototype;
child.prototype = new F;
child.prototype.constructor = child;
child.superproto = parent.prototype;
return child;
};
})();

欢迎转载,但转载请注明来自”勿忘初心”的博客,并保持转载后文章内容的完整性。

本文链接:http://lucylc.com/JavaScript/2018/04/22/实用型JavaScript方法总结.html

坚持原创技术分享,您的支持将鼓励我继续创作!

热评文章