JSデザインパターン:参加者モード

参加者モード:特定の役割に与えられた機能ドメインを実行します。そして、パラメータはそのまま渡さ

需要シナリオ:バックエンドのデータから引っ張っ時、キャッシュされ、ビューにユーザーがクリックすると、この情報を表示する必要があります

=「ボタンをクリックしてください、あなたはイベントのコールバック関数への追加データが必要

let A = { event: {} }

A.event.on = function(dom, type, fn) {
    if(dom.addEventListener) {
        dom.addEventListener(type, fn, false)
    }else if(dom.attachEvent) {
        dom.attachEvent('on' + type, fn)
    }else{
        dom['on'+ type] = fn 
    }
}


// 难点 addEventListener 不能传入data
// 解决 在回调函数里面做文章

A.event.on = function(dom, type, fn, data) {
    if(dom.addEventListener) {
        dom.addEventListener(type, function(e){
            fn.call(dom, e, data)
        })
    }
}

// 新问题: 添加的事件回调函数不能移除了
// 解决: bind apply改变this  apply 小demo


function bind(fn, context) {
    return function() {
        return fn.apply(context, arguments)
    }
}

var demoObj = {
    title: '这是一个demo',
}
function demoFn() {
    console.log(this.title)
}
var bindFn = bind(demoFn, demoObj)

bindFn() // 这是一个例子



var btn = document.getElementsByTagName('button')[0];

var p = document.getElementsByTagName('p')[0]

//改造
function demoFn() {
    console.log(arguments, this)
}

var bindFn = bind(demoFn)

btn.addEventListener('click', bindFn)    // [MouseEvent] Window {external: Object, chrome: Object, document: document, demoObj: Object, btn: button…}

bindFn = bind(demoFn, btn)

btn.addEventListener('click', bindFn)    // [MouseEvent] <button>​click me​</button>​


// 有些高级浏览器有提供bind函数 实现如下

var bindFn = demoFn.bind(demoObj)

/**
 * 函数柯里化: 对函数的参数分割, 类似于多态
 */

function curry(fn) {
    //缓存数据slice方法

    var slice = [].slice

    var args = slice.call(arguments, 1);

    return function() {
        var addArgs = slice.call(arguments),
            allArgs = args.concat(addArgs)

        return fn.apply(null, allArgs)
    }
}

function add(num1, num2) {
    return num1 + num2
}
function add5(num) {
    return 5+num
}

//用curry实现两种加法 函数的创建过程在curry里实现了
let add7= curry(add, 7, 8)
let add58 = curry(add, 5)


//重写bind
function bind(fn, context) {
    var slice = Array.prototype.slice,
    args = slice.call(arguments, 2)

    return function() {
        var addArgs = slice.call(arguments),
            allArgs = addArgs.concat(args);

        return fn.apply(context, allArgs)
    }
}


// 测试

var demoData1 = {
        text: '这是第一组数据'
    },
    demoData2 = {
        text: '第二个数据'
    }

bindFn = bind(demoFn, btn, demoData1) 

btn.addEventListener('click', bindFn)    // [MouseEvent, Object<demoData1>]  <button>​click me​</button>​
公開された13元の記事 ウォン称賛12 ビュー20000 +

おすすめ

転載: blog.csdn.net/Forever201295/article/details/104032369
おすすめ