You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
var T = function (selector) {
// 获取DOM元素
var dom = document.querySelector(selector);
// 添加类
dom.addClass = function (className) {
this.classList.add(className);
};
// 删除类
dom.removeClass = function (className) {
this.classList.remove(className)
};
return dom;
};
要解决的问题
上一节 #60 我们已经知道如何使用IIFE和闭包来处理模块化的问题。现在我们来尝试实现两个功能。
我们回想一下,jquery完成上面的功能大概是这样的。
我们分析一下。
工厂模式
ok,上最基础的工厂模式。
缺点
第一,返回的DOM元素无法知道它是从T这个构造函数中来的。
证据:
你可能会说,你这不废话吗!这里只用了工厂模式,压根没构造模式,哪儿来的构造函数!
没错,不过我们看看jquery
看见没?我们现在姑且可以认为jQuery那样做的好处在于起码我知道实例化的对象是从哪儿来的。
第二,每个dom实例的addClass和removeClass方法都会在内存中存一份,并不能共享,造成资源上的浪费。证明依据。
构造模式
我们先来尝试解决工厂模式的第一个缺点。
验证
发现第一个问题已经解决。我们来看第二个问题,函数复用问题。
我们把addClass和removeClass抽象成全局函数(注意,这里的全局是指自执行表达式里面的)
验证:
缺点
addClass和removeClass被声明为全局。虽然我们通过闭包将这种影响限制在模块内,但是这样子做也总感觉失去了对象的封装性。
原型模式
为了解决构造模式的全局函数声明问题,我们使用prototype来实现所谓的原型模式
shit.....忽然发现光用原型模式居然没法搞出一个demo来。比如一般的原型模式是这样的。
实际上这是会报错的
由此我们可以看到原型模式的一个重大缺陷:无法传递参数,也就是说每次构造出来的对象只能是一样的,这能忍?
当然,它还有另外一个重大缺陷,那就是传递引用。由于这里还不涉及到,就不说了。
混合模式
原型模式走不通,原因是因为不能传递参数。但是前面的构造函数可以传参啊,所以结合两者就是混合模式。
如何把new去掉?
目前我们已经做了很多了,但是还不够。比如,看下面的对比。
jquery实例化的时候是不需要new关键字的,而我们的T因为包含构造模式,所以得使用new。那么jquery是如何把new去掉的呢?(当然,new $('selector')也是可以执行的)
这里有一篇文章讲得很不错,http://www.cnblogs.com/aaronjs/p/3278578.html
下面我直接给出改造过后的代码
The text was updated successfully, but these errors were encountered: