一、最基本的创建对象的做法
1 var jQuery = function () { 2 // 构造函数 3 } 4 5 jQuery.prototype = { 6 version: '1.1.1', 7 name: function() { 8 console.log(this.version); 9 } 10 } 11 12 var a = new jQuery(); 13 14 a.name(); // "1.1.1"
这是在js里最基本的构建一个类的做法,但是如果当用户输入的是var a = jQuery(); ,就会出错。我们要让用户不需要进行new来创建,这样可以提升体验。
1 var jQuery = function(selector, context) { 2 return new jQuery(selector, context); 3 } 4 5 jQuery.prototype = { 6 name:function() { 7 // name方法 8 } 9 } 10 11 12 jQuery();
这是想法中应该这么写,但是明显的问题,死循环了。那么jQuery是怎么解决的呢?在jQuery中,使用jQuery.prototype.init来创建实例,这样就能防止死循环的问题。
1 var jQuery = function (selector, context) { 2 return new jQuery.prototype.init(selector, context); 3 } 4 5 jQuery.prototype = { 6 constructor: jQuery, 7 init: function(selector, context) { 8 return this; 9 }, 10 name: function () { 11 console.log("name调用"); 12 } 13 }
当我们调用name方法的时候报错了,因为我们实例化的是jQuery.prototype.init,这上面不会挂载jQuery的方法,同时通过原型链也访问不到。那么jQuery是怎么解决的呢?看下面的一行代码,也是我觉得很点睛之笔的地方。
1 var jQuery = function (selector, context) { 2 return new jQuery.prototype.init(selector, context); 3 } 4 5 jQuery.fn = jQuery.prototype = { 6 constructor: jQuery, 7 init: function(selector, context) { 8 return this; 9 }, 10 name: function () { 11 console.log("name调用"); 12 } 13 } 14 15 jQuery.fn.init.prototype = jQuery.prototype; 16 17 jQuery().name(); // name调用
我们通过把jQuery.fn.init的原型指向jQuery.prototype,这样我们在使用的时候就能够通过实例化的对象访问到挂载在jQuery.prototype上的属性。
我们可以将静态方法也就是我们的工具方法挂载在jQuery上,我们调用的时候不需要去实例化,而是可以直接去调用。将对象的方法挂载到jQuery.prototype上,我们系需要实例化之后才能够使用,针对的this的操作。