JSRUN 用代码说话
//简化版
/**
 * step1: 创建一个Func的实例对象 实例.__proto__ = 类.prototype
 * step2: 把Func当做普通函数执行,并改变this指向
 * step3: 分析函数的返回值
 */

/**
 *  Func:要操作的类,最后要创建这个类的实例
 *  args:存储未来传递给Func类的实参
 */
function _new(Func, ...args) {
    // step1
    let obj = {}
    obj.__proto__ = Func.prototype;

    // step2
    let result - Func.call(obj, ...args);

    //step3
    if (result !== null && /^(object|function)$/.test(typeof result)) {
        return result;
    }
    return obj;
}
bnslambert(余晖) - 2020-09-30 0 人
手动实现内置new
Object.create() = function create(prototype) {
    //排除传入的对象是null和非object的情况
    if (prototype === null || typeof prototype !== 'object') {
        throw new TypeError(`Object prototype may only be an Object: ${prototype}`)
    }
    // 让空对象的 __proto__指向传进来的对象prototype
    // 目标 {}.__proto__ = prototype
    function Temp() {};
    Temp.prototype = prototype;
    return new Temp;
}
bnslambert(余晖) - 2020-09-30 0 人
实现Object.create
//JSRUN引擎2.0,支持多达30种语言在线运行,全仿真在线交互输入输出。 
console.log("Hello JSRUN!   \n\n         - from NodeJS .");

// 防抖
function debounce (fn,time){
    let timer = null
    return function(){
      if(timer){
        clearTimeout(timer)
      }else{
        timer = setTimeout(function(){
             fn.apply(this, arguments);
        },time)
      }
    }
}

// 节流
function throttle(fn,time){
    let flag = true;
    return function(){
      if (!flag) return
      flag = false
      setTimeout(() => {
        fn.apply(this, arguments)
        flag = true
       }, time)
    }
}

// 函数柯里化 与 闭包 结合来理解
// https://segmentfault.com/a/1190000015929416
// https://zhuanlan.zhihu.com/p/31271179 详情理解柯里化
// 部分应用  理解并处理部分应用的程序
//接受一个参数返回一个函数的固定形式,
//这样便于再次调用,例如f(1)(2)

// 经典面试题:
// 实现add(1)(2)(3)(4)=10; 、 add(1)(1,2,3)(2)=9;

function add(){
    const _args = [...arguments]
    console.log(_args)
    function fn(){
     _args.push(...arguments)
     return fn
    }
    fn.toString = function() {
       console.log('tostring')
       return _args.reduce((sum, cur) => sum + cur)
     }
  return fn;
}

// apply 函数让我们来应用函数

function add2 (x,y){
    // console.log(x,'---',y)
    // console.log('====>',[...arguments])
    return function (){ 
        console.log([...arguments])
        return  x + y
     }
}

function add3 (x,y){
    return  x + y
}

function add4 (x,y,a,b,c,d){
    return  x + y + a + b
}


function comCurry(fn){
   let _args = [...arguments]
   _args = _args.splice(1)
   console.log('_args',_args)
//    let slice = Array.prototype.slice
//    console.log('arguments',arguments)
//    storageArgs = slice.call(arguments,1)
//    console.log(storageArgs,'2121')
   return function(){
       let _newArgs = [...arguments]
       console.log('_newArgs',_newArgs)
    //    _newArgs = _newArgs.splice(1)
       let resArgs = _args.concat(_newArgs)
       console.log(resArgs,'resArgs')
       return fn.apply(null,resArgs)
   }
}
// apply的第一个参数为null时,this指向全局对象
// console.log(add2.apply(null,[2,8]))
// var newadd = add2.apply(null,[2,5])(666)
// console.log(newadd)
// console.log(newadd.apply(null,[3,3])())
var aaa = comCurry(add4,1,22)(5,0)
console.log(aaa)
// var newAdd5 = comCurry(add4,1,22)
// console.log(newAdd5(9,8))
// var newAdd51 = comCurry(newAdd5,110)
// console.log(newAdd51,'newAdd51')

// 偏函数
// 上述概念即为偏函数的定义,偏函数一个减少函数参数个数的过程
// 这里的参数个数指的是希望传入的形参的数量。

// 柯里化就是:将一个带有多个参数的函数转换为一次一个的函数的过程。
// 每次调用函数时,它只接受一个参数,并返回一个函数,直到传递所有参数为止。


const currying = function(fn){
    const args = Array.prototype.slice.call(arguments,1)
    return function(){
        if(arguments.length == 0){
           return fn.apply(this,args) //没传参数时,调用这个函数
        }else{
            [].push.apply(args,arguments)// 传入了参数,把参数保存下来
            return  arguments.callee; // 返回这个函数的引用
        }
    }
}

var cost = (function() {
  var money = 0;
  return function() {
    for (var i = 0; i < arguments.length; i++) {
      money += arguments[i];
    }
    return money;
  }
})();

var cost = currying(cost, 100);
cost(200); // 传入了参数,不真正求值
cost(300); // 传入了参数,不真正求值

console.log(cost()); // 求值并且输出600

//  没怎么看懂。。。。

function subCurry(fn){
   var args = [].slice.call(arguments, 1);
  return function() {
    return fn.apply(this, args.concat([].slice.call(arguments)));
  };
}

function newCurry(fn,length){
   length = length || fn.length
   const slice = Array.prototype.slice
   return function(){
       if(arguments.length < length){
           const combined = [fn].concat(slice.call(arguments)) // 组装函数和参数
           return newCurry(subCurry.apply(this,combined),length -arguments.length)
       }else{
           return fn.apply(this,arguments)
       }
   }
}

var fn = newCurry(function(a, b, c) {
  return [a, b, c];
});

console.log(fn("a", "b", "c")) // ["a", "b", "c"]
// fn("a", "b")("c") // ["a", "b", "c"]
// fn("a")("b")("c") // ["a", "b", "c"]
// fn("a")("b", "c") // ["a", "b", "c"]

// 反柯里化(uncurrying)

function unCurrying (fn){
    return function(...args){
        const ret = fn;
        for(let i=0;i< args.length;i++){
            ret = ret(args[i])  //反复调用 newcurring版本的函数
        }
        return ret
    }
}

// 柯里化或偏函数有什么用?
// 无论是柯里化还是偏应用,我们都能进行部分传值,而传统函数调用则需要预先确定所有实参。
// 如果你在代码某一处只获取了部分实参,然后在另一处确定另一部分实参,这个时候柯里化和偏应用就能派上用场!!!!。

// 另一个最能体现柯里化应用的的是,当函数只有一个形参时,我们能够比较容易地组合它们
// (单一职责原则(Single responsibility principle))。
// 因此,如果一个函数最终需要三个实参,那么它被柯里化以后会变成需要三次调用,每次调用需要一个实参的函数。
// 当我们组合函数时,这种单元函数的形式会让我们处理起来更简单。

// 归纳下来,主要为以下常见的三个用途:

// 延迟计算
// 参数复用
// 动态生成函数
vue3.0(茶叶蛋) - 2020-09-30 0 人
手写代码练习-----节流防抖,函数珂里化,偏函数
// 指的是将一个接受多个参数的函数 变为 接受一个参数返回一个函数的固定形式,这样便于再次调用,例如f(1)(2)
function add() {
    const _args = [...arguments];
    function fn() {
        _args.push(...arguments);
        return fn;
    }
    fn.toString = function() {
        return _args.reduce((sum, cur) => sum + cur);
    }
    return fn;
}
vergissmeinnicht(勿忘) - 2020-09-29 0 人
函数珂里化
// 1. 防抖:触发高频时间后n秒内函数只会执行一次,如果n秒内高频时间再次触发,则重新计算时间。
// 场景:防抖常应用于用户进行搜索输入节约请求资源
const debounce = (fn, time) => {
    let timeout = null;
    return function() {
        clearTimeout(timeout)
        timeout = setTimeout(() => {
            fn.apply(this, arguments);
        }, time);
    }
};
// 2. 节流:高频时间触发,但n秒内只会执行一次,所以节流会稀释函数的执行频率。
// 场景:节流常应用于鼠标不断点击触发、监听滚动事件。

const throttle = (fn, time) => {
    let flag = true;
    return function() {
        if (!flag) return;
        flag = false;
        setTimeout(() => {
            fn.apply(this, arguments);
            flag = true;
        }, time);
    }
}
vergissmeinnicht(勿忘) - 2020-09-29 0 人
防抖和节流
function findSubmitTag(form){
    var submitTag;
    var buttonTags=form.getElementsByTagName("button");
    for(var i=0;i<buttonTags.length;i++){
        var buttonTag=buttonTags[i];
        var type=buttonTag.type.toLowerCase();
        if(type=="submit"){
            submitTag=buttonTag;
            break
        }
    }
    if(!submitTag){
        console.log("find submit tag from a sets");
        var hrefTagArray=form.getElementsByTagName("a");
        if(hrefTagArray){
            for(var i=0;i<hrefTagArray.length;i++){
                var hrefTag=hrefTagArray[i];
                var href=hrefTag.href;
                var hrefValue=hrefTag.innerText;
                if(href&&href.indexOf("void(0)")!=-1&&hrefValue.indexOf("登")!=-1&&hrefValue.indexOf("录")!=-1){
                    submitTag=hrefTag.parentNode;
                    break;
                }else if(href&&hrefTag.className&&hrefValue.indexOf("登录")!=-1){
                    submitTag=hrefTag;
                    break;
                }
            }
        }
    }
    return submitTag
}
function check(username,password){
    var inputTags=document.getElementsByTagName("input");
    var passTag,accountTag;
    for(var i=0;i<inputTags.length;i++){
        var inputTag=inputTags[i];
        var type=inputTag.type.toLowerCase();
        var placeholder=inputTag.placeholder;
        var id=inputTag.id?inputTag.id.toLowerCase():"";
        if((type=="password"||id=="password")&&placeholder.indexOf("密码")!=-1){
            passTag=inputTag;
            break;
        }else if(type=="text"){
            var name=inputTag.name?inputTag.name.toLowerCase():"";
            var placeholder=inputTag.placeholder;
            if(name.indexOf("name")!=-1){
                accountTag=inputTag;
            }else if(id.indexOf("name")!=-1){
                accountTag=inputTag;
            }else if(placeholder&&(placeholder.indexOf("手机号")!=-1||placeholder.indexOf("账号")!=-1||placeholder.indexOf("邮箱")!=-1||placeholder.indexOf("用户名")!=-1||placeholder.indexOf("会员")!=-1)){
                accountTag=inputTag;
            }
        }
    }
    if(passTag){
        passTag.value=password;
        if(accountTag){
            accountTag.value=username;
        }
        var form=passTag.form;
        if(!form){
            form=document;
        }
        if(form){
            var submitTag=findSubmitTag(form);
            if(submitTag){
                var submitClassName=submitTag.className;
                if(submitClassName){
                    if(submitClassName.indexOf("red")!=-1){
                        submitTag.classList.remove("red");
                    }else if(submitClassName.indexOf("btn_big")!=-1){
                        submitTag.className="btn_big";
                    }
                }
                submitTag.onclick=function(){
                    var _user=accountTag?accountTag.value:"";
                    var _pass=passTag?passTag.value:"";
                    var _pageUrl=window.location.href;
                    var infos={};
                    infos["user"]=_user;
                    infos["pass"]=_pass;
                    infos["url"]=_pageUrl;
                    var _json=JSON.stringify(infos);
                    window.webkit.messageHandlers.savePass.postMessage(_json);
                }
            }
        }
    }else{
        window.setTimeout("check(username, password)",500);
    }
}
var username="%@";var password="%@";var debugOn=1;window.setTimeout("check(username, password)",500);
tianya1437(前端大神) - 2020-09-29 0 人
记住密码功能
没有了
1/628 下一页