原型是javascript的核心概念也是较难理解的,本篇主要介绍原型的一些概念,且与构造函数属性、构造函数方法的区别,最后结合Jquery与Zepto在实际工作中的应用进行分析介绍,希望对您有帮助。
我们所创建的每个原型都有一个(原型)属性,这个属性是一个对象。
- 先查找构造函数实例里的属性或方法,如果有,立刻返回
- 如果构造函数实例里没有,则去它的原型对象里找,如果有,就返回
functionBox(name,age){this.name=name;//实例属性this.age=age;this.run=function(){//实例方法returnthis.name+this.age+"运行中.....";};}varbox1=newBox('zhangsan',20);varbox2=newBox('lisi',18);alert(box1.run==box2.run);//false构造函数体内什么都没有,这里如果有,叫作实例属性,实例方法
functionBox(){}Box.prototype.name='lee';//原型属性Box.prototype.age=23;Box.prototype.run=function(){//原型方法returnthis.name+this.age+"运行中......";};如果是实例化方法,不同的实例化,他们的地址是不一样的,是唯一的,如果是原型方法,那么他们地址是共享的,大家都一样,看以下示例box1.run==box2.run。
varbox1=newBox();varbox2=newBox();alert(box1.run==box2.run);// true这个属性是一个对象,访问不到
alert(box1.prototype);这个属性是一个指针指向prototype原型对象
alert(box1._proto_);构造属性可以获取构造函数本身,作用是被原型指针定位,然后得到构造函数本身,其实就是对象实例对应的原型对象的作用
alert(box1.constructor);使用构造函数创建原型对象和使用字面量创建对象在使用上基本相同,但还是有一些区别,字面量创建的方式使用constructor属性不会指向实例,而会指向Object,构造函数则相反。
functionBox(){}使用字面量的方式创建原型对象,这里{}就是对象(Object),new Object就相当于{}
Box.prototype={name:'lee',age:20,run:function(){returnthis.name+this.age+"运行中.......";}};varbox1=newBox();alert(box1.constructor);//返回function Object(){}对象functionBox(name,age){this.name=name;this.age=age;this.run=function(){returnthis.name+this.age+"运行中....";};}varbox1=newBox('zhangsan',20);alert(box1.constructor);//返回的是function Box(){}- 重写原型对象之后,不会保存之前原型的任何信息
- 把原来的原型对象和构造函数对象实例之间的关系切断了
functionBox(){}Box.prototype={constructor:Box,//让它强制指向Boxname:'lee',age:20,run:function(){returnthis.name+this.age+"运行中.......";}};重写原型
Box.prototype={age:21}varbox1=newBox();alert(box1.name);// undefined可以使用addstring()方法向原型添加内容,这样可以避免原型重写
String.prototype.addstring=function(){returnthis+',被添加了!';};varbox1=newBox();alert(box1.name.addstring());// lee,被添加了!- 先找到入口函数
window.$ - 根据入口函数找到构造函数
new ... - 根据构造函数找到原型的定义
zepto.Z.prototype
以下实例中通过Jquery或Zepto操作dom元素,例如css方法、text方法都是操作的原型上的的方法。
<!DOCTYPE html><htmllang="en"><head><title>Zepto</title><!--<script src="https://cdn.bootcss.com/zepto/1.1.6/zepto.js"></script> <script src="zepto.js"></script> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script> --><scriptsrc="jquery.js"></script></head><body><div> 这是一个测试 </div><div> 这是一个测试2 </div><script>vardiv=$('div');// 得到一个实例div.css('color','red');// 原型方法cssalert(div.text());// 原型方法text</script></body></html>Zepto源码地址:https://cdn.bootcss.com/zepto/1.1.6/zepto.js
以下实例也是取了关于原型部分的源码
varZepto=(function(){var$,zepto={},emptyArray=[],slice=emptyArray.slice,document=window.document;// 构造函数zepto.Z=function(dom,selector){dom=dom||[]dom.__proto__=$.fndom.selector=selector||'';returndom}zepto.init=function(selector){vardom;// 如果选择器不存在,返回一个空的Zepto集合if(!selector)returnzepto.Z();// 优化字符串选择器if(typeofselector==='string'){selector=selector.trim();// 还有一系列的判断此处忽略,进行简化 ...dom=slice.call(document.querySelectorAll(selector))}else{// 更多可以去查看源码 ...}returnzepto.Z(dom,selector)}$=function(selector){returnzepto.init(selector);}$.fn={text: function(){return(0inthis ? this[0].textContent : null)},css: function(){alert('css');}}// $.fn赋值给构造函数的原型zepto.Z.prototype=$.fn;return$;})()window.Zepto=Zepto;window.$===undefined&&(window.$=Zepto);// 如果window.$不存在,赋予window.$为Zepto;Jquery源码地址:https://cdn.bootcss.com/jquery/3.3.1/jquery.js
(function(global,factory){// 浏览器环境、Node环境判断if(typeofmodule==="object"&&typeofmodule.exports==="object"){// Node环境处理,这里不做阐述,具体参考源码// factory(global, true);}else{// 进入浏览器环境factory(global);}})(typeofwindow!=="undefined" ? window : this,function(window,noGlobal){varJquery=function(selector){returnnewjQuery.fn.init(selector);}Jquery.fn=Jquery.prototype={css: function(){alert('css');},text: function(){return(0inthis ? this[0].textContent : null);}};// 定义构造函数varinit=Jquery.fn.init=function(selector){varslice=Array.prototype.slice;vardom=slice.call(document.querySelectorAll(selector));vari,len=dom ? dom.length : 0;for(i=0;i<len;i++){this[i]=dom[i];}this.length=len;this.selector=selector||'';}// 构造函数原型赋值init.prototype=Jquery.fn;if(!noGlobal){// 判断是否为浏览器环境window.jQuery=window.$=Jquery;}})- 插件扩展在
$.fn之上,并不是扩展在构造函数的原型 - 对外开放的只有
$,构造函数并没有开放
在Zepto中把原型方法放在$.fn上,在Jquery中把原型方法放在Jquery.fn之上,之所以这样做是为了后期插件扩展所需。
实例:
<body><script>// 插件扩展:获取tagName$.fn.getTagName=function(){return(0inthis ? this[0].tagName : '');}</script><div> 这是一个测试 </div><div> 这是一个测试2 </div><script>vardiv=$('div');// 得到一个实例alert(div.getTagName());// 封装的插件</script></body>