一些奇淫技巧整理

函数节流的代码实现:

let throttle = function (fn, interval) {
      let _self = fn,       //保存需要被延迟执行的函数引用
          timer,            //定时器
          firstTime = true; //是否第一次调用
      return function () {
          let args = arguments;
          let _me = this;
          if(firstTime){
              _self.apply(_me,args);
              return firstTime = false;
          }
          if(timer){
              return false;
          }
          timer = setTimeout(function () {
              clearTimeout(timer);
              timer = null;
              _self.apply(_me, args);
          }, interval || 500);
      };
    };
    window.onresize = throttle(function () {
        console.log(1);
    },500);

throttle 函数的原理是: 将即将被执行的函数 setTimeout 延迟一段时间执行,如果该次延迟执行还没有完成,则忽略接下来调用该函数的请求。fn 为需要被延迟执行的函数,interval 为延迟执行的时间。

4、分时函数 timeThunk

 let timeChunk = function (ary,fn,count) {
        let obj,t;
        let len = ary.length;
        let start = function () {
            for(let i = 0; i                 let obj = ary.shift();
                fn(obj);
            }
        };
        return function () {
            t = setInterval(function () {
                if(ary.length === 0 ){
                    return clearInterval();
                }
                start();
            }, 200);
        };
    }

 

timeThunk 接受三个参数,第一个是创建节点需要用到的数据,第二个参数是封装了节点逻辑的函数,第三个参数是表示每一批创建的节点数量。

 

降低全局变量带来的命名污染:

1、动态创建命名空间:

一些奇淫技巧整理_第1张图片

 2、使用闭包封装私有变量

let user = (function () {
        let _name = 'Shrijin',
            _age = 21;
        return {
            getUserInfo: function () {
                return _name + '-' + _age;
            }
        }
    })();

把一些变量封装在闭包的内部,只暴露一些接口和外界通信,外部就访问不到私有变量,这样就避免了全局的命名污染。

 

以下代码在不同的浏览器控制台有不同的输出

function Foo(){}
    let fn = new Foo();
    fn;

在Chrome的控制台输入 fn ,回车得到的是 Foo{ }

在Firefox控制台输出的是 Object { }

在《You don't know JS》中,提到Chrome想说的是 { } 是一个空对象,由名为Foo的函数构造; 而Firefox想说的是{ }是一个空对象,由Object 创建。之所以有这种细微的差别,是因为Chrome会动态跟踪并把实际执行构造过程的函数名当作一个内置属性,而其他浏览器并不会跟踪这些额外的信息。

 

隐藏滚动条的CSS3样式解决兼容写法:

html { overflow: -moz-hidden-unscrollable; height: 100%; }

body::-webkit-scrollbar { display: none; }

body { -ms-overflow-style: none; height: 100%; width: calc(100vw + 18px); overflow: auto; }有时内容还要根据需要来添加width:100vw

 

Generator 函数实现斐波那契数列:

function* fibonacci() {
            let [prev, curr] = [0, 1];
            for (;;) {
                [prev, curr] = [curr, prev + curr];
                yield curr;
            }
        }

        for (let n of fibonacci()) {
       //  输出1000以内的斐波那契数列项
            if (n > 1000) break;
            console.log(n);
        }

 

yield* 语句可以方便快捷地取出嵌套数组中的成分

function* iterTree(tree) {
            // debugger;
            if (Array.isArray(tree)) {
                for (let i = 0; i < tree.length; i++) {
                    yield* iterTree(tree[i]);
                }
            } else {
                yield tree;
            }
        }
        const tree = ['a', ['b', 'c'], ['d', 'e']];
        for (let x of iterTree(tree)) {
            console.log(x);
        }

 

利用Generator 函数,可以在任意对象上部署Iterator接口

 function* iterEnties(obj) {
            let keys = Object.keys(obj);
            for (let i = 0; i < keys.length; i++) {
                let key = keys[i];
                yield [key, obj[key]];
            }
        }
        let myObj = { foo: 3, bar: 7};
        for (let [key, value] of iterEnties(myObj)) {
            console.log(key, value);
        }

 

setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise.resolve()在本轮“事件循环”结束时执行,console.log(’one‘)则是立即执 行

setTimeout(function () {
            console.log('three');
        }, 0);
        Promise.resolve().then(function () {
            console.log('two');
        });
        console.log('one');

// 输出
// one
// two
// three

 

Promise对象的回调链,不管以then方法或catch方法结尾,要是最后一个方法抛出错误,都有可能无法捕捉到(因为Promise内部的错误不会冒泡到 全局)。提供一个done方法,总是处于回调链的尾端,保证抛出任何可能出现的错误。

Promise.prototype.done = function (onFulfilled, onRejected) {
            this.then(onFulfilled, onRejected)
                .catch(function (reason) {
                // 抛出一个全局错误
                setTimeout(() => { throw reason }, 0);
            });
        };

finally方法用于指定不管Promise对象最后状态如何,都会执行的操作。它与done方法的最大区别,它接受一个普通的回调函数作为参数,该函数不 管怎样都必须执行。

Promise.prototype.finally = function (callback) {
            let P = this.constructor;
            return this.then(
                value => P.resolve(callback()).then(() => value),
                reason => P.resolve(callback()).then(() => { throw reason })
            );
        };

 

任何函数,只要参数有回调函数,就能写成Thunk函数的形式。es5 和ES6版本的Thunk 函数转换器

let ThunkEs5 = function (fn) {
            return function () {
                var args = Array.prototype.slice.call(arguments);
                return function (callback) {
                    args.push(callback);
                    return fn.apply(this, args);
                }
            };
        };

        // es6版本
        let ThunkEs6 = function (fn) {
            return function (...args) {
                return function (callback) {
                    return fn.call(this, ...args, callback);
                }
            };
        };

 

你可能感兴趣的:(JavaScript)