读到jquery源码时我有以下迷惑
题目1 Jquery
中建立对象的奥妙
题目2 JavaScript
中this
的指向题目
题目3 return this
的作用
题目4 instanceof
/ 对象和类之间的关联
//代码1(Jquery 建立对象)
var iQuery=function (){
name="iQuery"; //4
return new iQuery.prototype.init(); //1
};
iQuery.prototype={
init : function(){
name="iQueryPrototypeInit"; //5
return this; //2
},
name : "iQueryPrototype" //6
};
iQuery.prototype.init.prototype=iQuery.prototype; //3
这时候我有题目了,//1 处有没有new
的区分。//2 处有没有 return this
的区分。 //3处的作用
在这里我经由过程对//代码1 举行剖析来回复 题目1 到 题目4
//代码2 我将 //代码1 中的 //3 处去掉 //2 处去掉 //1 处去掉
var iQuery=function (){
name="iQuery";
return iQuery.prototype.init();
};
iQuery.prototype={
init : function(){
name="iQueryPrototypeInit"; //5
},
name : "iQueryPrototype"
};
iQuery().name; //效果为 VM105:1 Uncaught TypeError: Cannot read property name of undefined(…)
剖析: iQuery.prototype.init()
是挪用了init
函数,由于函数没有返回值,所以只返回了掌握 return iQuery.prototype.init()
也没有返回值iQuery().name;
会有以上毛病提醒
//代码3
var iQuery=function (){
name="iQuery"; //4
return new iQuery.prototype.init(); //1
};
iQuery.prototype={
init : function(){
name="iQueryPrototypeInit"; //5
},
name : "iQueryPrototype" //6
};
iQuery().name; //效果为 undefined 这里并不提醒毛病,而是说name没有定义;
剖析: //4处 name
为iQuery
的局部变量,//5 处name
是init
的局部变量。
实行iQuery()
时建立了一个init的对象,这时候init是组织函数,实行时流程
1 建立一个对象
2 返回新建的对象
这就是有没有 new
的区分
//代码4 多了个this
var iQuery=function (){
name="iQuery"; //4
return new iQuery.prototype.init(); //1
};
iQuery.prototype={
init : function(){
this.name="iQueryPrototypeInit"; //5
},
name : "iQueryPrototype" //6
};
iQuery().name; //效果为 `iQueryPrototypeInit`
剖析: 实行 iQuery().name;
实行流程
1 建立一个对象
2 让 this
援用这个对象
3 为 this
所援用的对象增加属性 name
4 返回 this
所援用的对象
iQuery() instanceof iQuery //false
iQuery() instanceof iQuery.prototype //VM125:1 Uncaught TypeError: Right-hand side of 'instanceof' is not callable(…)
说 iQuery.prototype
是一个对象 instanceof
右侧必需是类,即函数名
iQuery() instanceof iQuery.prototype.init; //true
这里挪用 iQuery()
是建立了init
的一个对象。
//代码5 多了//2
var iQuery=function (){
name="iQuery"; //4
return new iQuery.prototype.init(); //1
};
iQuery.prototype={
init : function(){
this.name="iQueryPrototypeInit"; //5
return this; //2
},
name : "iQueryPrototype" //6
};
iQuery().name; //效果为 iQueryPrototypeInit
剖析: 实行 iQuery().name;
实行流程
1 建立一个对象
2 让 this
援用这个对象
3 为 this
所援用的对象增加属性 name
4 返回 this
所援用的对象
iQuery() instanceof iQuery //false
iQuery() instanceof iQuery.prototype //VM125:1 Uncaught TypeError: Right-hand side of 'instanceof' is not callable(…)
说 iQuery.prototype
是一个对象 instanceof
右侧必需是类,即函数名
iQuery() instanceof iQuery.prototype.init; //true
这里挪用 iQuery()
是建立了init
的一个对象。
总结1 假如运用new建立对象加不加 return this 是一样的。
//代码6 去掉//1 处的 new
//2处有 return this
var iQuery=function (){
name="iQuery"; //4
return iQuery.prototype.init(); //1
};
iQuery.prototype={
init : function(){
this.name="iQueryPrototypeInit"; //5
return this; //2
},
name : "iQueryPrototype" //6
};
iQuery().name; // iQueryPrototypeInit
假如去掉 //5
iQuery().name; // iQueryPrototype
剖析: 实行 iQuery()
返回了 iQuery.prototype
这个由字面常量建立的对象
假如没有去掉 //5 则给 iQuery.prototype
增加了 name
属性覆蓋了原有的name
在这里 iQuery.prototype.init()
是 iQuery.prototype
这个对象挪用了 init
函数
所以 init
的 this
指向了 iQuery.prototype
结论2: 函数中的 this 一直指向直接挪用它的对象 ,注重是直接,为何说是直接 请看 //代码6
//代码7
var iQuery=function (){
name="iQuery"; //4
return iQuery.prototype.init(); //1
};
iQuery.prototype={
init : function(){
return this; //2
},
name : "iQueryPrototype" //6
};
var temp ={};
temp.name="temp";
temp.sayName=iQuery().init; // 等价于 temp.sayName=iQuery.prototype.init;
temp.name; // 效果 temp
temp.sayName.name; // 效果 temp
剖析: 实行 temp.sayName=iQuery().init;
为对象 temp
增加了一个 sayName
要领,sayName
援用了 iQuery().init
/temp.sayName=iQuery.prototype.init
这时候 init
中的 return this
这个 this
指向 temp
由于是 temp
直接挪用 init
总结:JavaScript中的 this 是上下文 这个上下文特指是函数的上下文,就是函数所属的对象JavaScript中的 bind,call,apply 要领都能切换 函数的上下文,这和代码 //6 的道理雷同都是转变 this 的指向,所以叫做上下文切换
//代码8 (本文最主要的点) 对象和类之间的关联(instanceof)
var iQuery=function (){
name="iQuery"; //4
return new iQuery.prototype.init(); //1
};
iQuery.prototype={
init : function(){
},
name : "iQueryPrototype" //6
};
iQuery.prototype.init.prototype=iQuery.prototype; //3
// 注重 增加了 //3
这时候实行:
a: iQuery() instanceof iQuery().init; //true
b: iQuery() instanceof iQuery; //true;
假如去掉 //3
c: iQuery() instanceof iQuery; //false;
剖析: 我挪用 iQuery() 建立的明显是 组织器 init 的对象啊 a:的效果才是相符逻辑的效果,b: 是什么鬼啊,和他有毛关联啊
请看 //代码9 //代码10
//代码9
var pro={};
var A=function(){};
A.prototype=pro;
var B=function(){};
B.prototype=pro;
var a=new A();
var b=new B();
实行:
a instanceof A; //true
a instanceof B; //true
b instanceof A; //true
b instanceof B; //true
//代码10
var pro={};
var A=function(){};
A.prototype=pro;
var B=function(){};
B.prototype=pro;
var a=new A();
var b=new B();
var C=function(){};
C.prototype=a;
var c=new C();
c instanceof A; //true
c instanceof B; //true
c instanceof C; //true
剖析: 看到这里人人一定会邃晓Jquery的设计者为何加 iQuery.prototype.init.prototype=iQuery.prototype;
虽然源码中用了 fn 然则 fn 就是 Jquery.prototype我给出我的结论
结论3: JavaScript 中的对象和类(即 组织器) 之间除了 对象的_proto_ 属性指向了 类(组织器)指定的 prototype以外,对象和类之间没有更多的关联。范例完全由 prototype 决议。具有雷同 prototype 的一切组织器的对象都具有雷同的范例
末了: Jquery
中的init
中有 return this
关于运用 new 函数名()
如许的体式格局建立对象有没有 return this
是一样的。那Jquery
为何加啊,由于Jquery
中的许多别的要领能够举行链式挪用,这些要领中经由过程 return this
返回由init
建立的对象,为了保持一致 所以init
中的 return this
真的能够去掉。关于运用 new 函数名()
建立 对象 return this
和无返回值一样由于默许就会返回 this
。 return 基础范例
,则 return
会被疏忽依旧 return this
。 假如 return 援用范例
那末返回效果就是 援用范例的对象。