如题,这个题目我曾经在支付宝的电话口试内里末了一个题目被问到过,厥后也没有去看究竟为什么不需要new,如今我们就来理会下。
而且当你在看jquery源码的时刻,假如一开始就搞不懂如许的题目,抑或jQuery.fn.init.prototype =jQuery.fn 如许的题目也搞不懂的话,那基础背面的东西都是懵的。
起首回忆下,我们平常是怎样写插件的,通常是如许的
function Kissy () {
}
Kissy.prototype.alert = function () {
}
// 实例化必需要有,不然没法挪用原型链上的alert要领
var kissy = new Kissy()
kissy.alert()
// 假如我们直接如许挪用
Kissy().alert()
// 就会报错alert不是一个function。这里涉及到原型继续,new 一个组织函数和 实行一般函数的区分,不在赘述。
回归一个知识点,有助于我们明白背面我们解说的内容
组织函数有return值怎么办?
组织函数里没有显式挪用return时,默许是返回this对象,也就是新创建的实例对象。
当组织函数里挪用return时,分两种状况:
1.return的是五种简朴数据类型:String,Number,Boolean,Null,Undefined。
这类状况下,无视return值,依旧返回this对象。
2.return的是Object
这类状况下,不再返回this对象,而是返回return语句的返回值。
怎样革新上面的代码,能够不必new函数,直接挪用到alert要领呢?很简朴。革新以下:
function Kissy () {
return Kissy.prototype
}
当我们直接挪用Kissy()函数的时刻,不是返回的null或undefined而是返回Kissy的原型,即返回了一个原型对象,这个对象上是有alert要领的,这就彷佛我们熟习的下面的代码一样
var obj = {
name: 'zj',
getName: function() {
console.log(this.name)
}
}
obj.getName() // zj
接下来,我们仿制jquery源码又来革新下:
function Kissy () {
return new Kissy.fn.init()
}
Kissy.fn = Kissy.prototype = {
constructor: Kissy,
init: function() {
console.log('init')
}
}
Kissy.fn.init.prototype = Kissy.fn
Kissy.fn.alert = function() {
alert('0000')
}
Kissy().alert() // 00000
不过就是在Kissy上面增添了一个fn属性,这个属性指向了Kissy.prototype。如许的目标是便于我们开辟插件的时刻,在原型上增添要领能够直接这么写Kissy.fn.alert 仅此而已。为什么组织函数不直接返回
Kissy.fn呢 而是在中心搞了一个init.读过jquery源码的都晓得,jquery.fn.init 这个函数现实是jquery的初始化函数。这里就不在展开了。
return new Kissy.fn.init()
组织函数返回了一个Kissy.fn.init()这个函数的一个实例。固然就会继续这个实例上的原型,而原型又被我们重置了
Kissy.fn.init.prototype = Kissy.fn
所以就可以挪用到Kissy.fn上面的alert要领了,不信人人能够尝尝哦。
再来看jquery的源码,对照方才剖析的代码,是否是基础如出一辙,只是jquery源码fn.init要领有比较多初始化的内容。
jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context, rootjQuery );
},
jQuery.fn = jQuery.prototype = { //fn即对应prototype
constructor: jQuery,
init: function( selector, context, rootjQuery ) {
...
return this;
}
...
}
jQuery.fn.init.prototype = jQuery.fn;