对于前端开发有一段时间的人来说,简单的交互和需求实现已不能满足对技术的追求感,如何能体现前端价值,那便是能写出高质量,高维护,高可读的代码,结合项目开发的空隙时间,我写了一个简单的demo来通俗的介绍下高大上的观察者模式到底是什么东东(vue双向数据绑定的原理( 数据劫持:observe,compile,whatcher)),同时也顺带介绍了下apply()和call()方法的使用。废话不多说,直接上代码吧!
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<button class="btn-test">点击</button>
<script type="text/javascript">
/*
* 测试 apply() Funtion.apply(this,args) 换句话来说就是当前this能够调用Funtion中定义的属性和方法(继承)而 args会作为Funtion的参数传进Funtion中
*/
//----------------------------测试1------------------------------
// var f1 = function( fn ) {
// fn.apply( this,['这是我想说的话'] );
// }
//
// var f2 = function( data ) {
// console.log(this)
// }
//// f2()
// f1(f2)
//---------------------------测试2-------------------------------
// function fParent( name,age ) {
// this.name = name;
// this.age = age;
// this.sayName = function(){
// console.log(this.name)
// }
// }
// function fExtend( n,a ) {
// fParent.call( this,n,a ) //这里利用call()方法使得当前的fExtend可以调用fParent定义的属性和函数
// }
// var fE = new fExtend('呵呵',12);
// fE.sayName();
//同理我们借助call()或者apply()来实现一些常用的技巧
//获取数组中最大值
// var arrs1 = [1,2,4];
// var theMax = Math.max.apply( null,arrs1 )
// console.log(theMax)
/*
* 观察者模式
*/
var btnTest = document.getElementsByClassName('btn-test')[0];
var objs = {};//发布者
objs.arr = [];//事件容器
objs.on = function( eventType,handles ) {//发布事件
//匹配 事件 是否存在容器中
var isEsit = this.arr[eventType];
//console.log("判断是否存在该事件:" + isEsit)
if( !isEsit ) {
//不存在则在事件容器中新增一个 ( 以事件名为Key,数组为value的) 值
this.arr[eventType] = [];
};
this.arr[eventType].push(handles);
};
objs.emit = function(e) {//事件订阅
//匹配 事件 是否存在容器中
var isEsit = this.arr[e];
if( !isEsit ) {
console.log('该事件不存在!');
return ;
}
var len = this.arr[e].length;
var args = Array.prototype.slice.apply( arguments,[1] );//利用apply使得类数组arguments可以调用数组的slice方法,并切割该arguments 1表示切割位置
// console.log( "长度:" + len );
// console.log( "参数:" + args );
this.arr[e].forEach(function( item ) {
return item.call( this,args );
})
}
// objs.on( 'click',function( data ) {
//
// console.log( '我是封装的方法!' + data );
//
// } );
objs.on( 'sayHellow',function( data ) {
console.log( '我要说的是:' + data );
} );
// objs.emit(1,2,3) //测试结果:假如在emit函数中没有对应的形参,则默认只能在函数中获取实参中第一个 这里只能获取1
// console.log( objs.arr ) //测试结果:数组其实也是对象,只不过平时它的下标就是key 而我们也可以指定它的key为非数字
btnTest.onclick = function() {
objs.emit( 'sayHellow','你那电脑5000块卖我呗^_^' );
}
</script>
</body>
</html>