一、由jQuery创建类引发的问题
在用jQuery选择器时候,可以通过下面两种方式获取元素,并得到一个jQuery对象。
var d1 = jQuery('#demo01'); var d2 = new jQuery('#demo02');
上面两种方式操作结果一致,这让我很好奇,自己模拟了一个类似的实现。
(function(global, undefined){ var jQuery = function(selector, context){ if(!(this instanceof jQuery)) { return new jQuery(selector, context); } /** other code **/ } global.jQuery = jQuery; })(window);
但是我发现这种方式好像也不杂滴,就跑去看了一下jquery源码的实现。
二、jQuery类的实现
上图是自己画的jQuery类创建图。其中jQuery.fn.init函数完全可以用另外一个函数名代替。代码很简单,不能理解的可能就jQuery类的创建代码是如此的少,仅用return new一个实例化对象就结束,这个简洁的有点让人惊叹,同时充满疑问,你丫是怎么同时保证过通过new和不通过new创建对象保持一致的呢?带着这个疑问,我们得深入研究一下关键词new的工作原理。
三、new的工作原理
众所周知,JavaScript借鉴其他一些面向对象对象语言的语法糖来实现自己的一些面向对象过程,其中最典型的就是关键词new。经过我一番测试后,对new一些理解:
1.通过操作构造函数实例化一个对象;
2.执行函数中如果有return,且返回值不是对象时候,直接抛弃,返回this,否则就return返回值对象。(之前这一点个人理解有误,这一点也是也就解释了上面jquery的那段代码)
至于new的工作原理,也很简单:
function createObject(constructor) { var o = {}, //第一步,创建一个初始化对象。 params = [].slice.call(arguments,1) || []; //分离出参数 var tmp = constructor.apply(o, params); //第二步,切换作用域,让构造函数中的this指向当前对象o,然后执行构造函数函数。 if(typeof tmp != 'object') { return tmp; } o.__proto__ = constructor.prototype; //第三步,设置原型链 o.constructor = constructor; //第四步,设置构造器 return o; }
四、总结
这次文章比较水,知识点比较简单,但就这么简单的问题,我之前还没弄明白,的确惭愧。知识重在积累,我必须得不断学习。