原型链:实例对象与原型之间的连接,叫做原型链
原型链的最外层 : Object.prototype
function Aaa(){
//构造函数
}
Aaa.prototype.num=30p; //扩展原型方法
var a1=new Aaa(); //创建对象
原型检测相关:
hasOwnProperty:看是不是对象自身的属性
具体概念:用来判断一个对象是否有你给出名称的属性或对象,不过需要注意:次方法无法检测到原型链中是否具有该属性,该属性必须是对象本身的一个成员
1 var arr=[]; 2 arr.num=10; 3 Array.prototype.num2=20; 4 console.log(arr.hasOwnProperty('num'));//true 5 console.log(arr.hasOwnProperty('num2'));//false
isPrototypeOf:是用来判断原型链对象是否存在指定对象实例中,则返回true,否则返回false
constructor 属性返回对创建此对象的数组函数的引用
1 function Aaa(){ 2 3 } 4 var a1=new Aaa(); 5 alert(a1.constructor);//function Aaa(){}
function Aaa(){
}
alert(Aaa.prototype.constructor==Aaa); //true 每一个函数都会自动生成的
Object.constructor
我们在定义函数的时候,函数定义的时候函数本身就会默认有一个prototype的属性,
而我们如果用new 运算符来生成一个对象的时候就没有prototype属性。我们来看一个例子,来说明这个
1 function a(c){ 2 this.b = c; 3 this.d =function(){ 4 alert(this.b); 5 } 6 } 7 var obj = new a('test'); 8 alert(typeof obj.prototype);//undefine 9 alert(typeof a.prototype);//object
a.prototype 包含了2个属性,一个是constructor ,另外一个是__proto__
这个constructor 就是我们的构造函数a,这个也很容易理解。
那么__proto__ 是什么呢?
这就涉及到原型链的概念
每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性时,如果对象内部不存在
这个属性就会到__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是一直走下去。
obj.__proto__===a.prototype //true
同理,这里我们分析出new运算符做了那些事情
1.var obj={}; 也就是说初始化一个对象obj
2.obj.__proto__=a.prototype;
3.a.call(obj) 也就是构造obj,也可以称为初始化obj
instanceof:对象与构造函数在原型链上是否有关系
1 function Aaa(){ 2 } 3 4 var a1 = new Aaa(); 5 6 alert( a1 instanceof Object ); //true 7 8 var arr = []; 9 10 alert( arr instanceof Array );
toString() :系统对象下面都是自带的,自己写的对象通过原型链找object下面的
将逻辑值转换成字符串
继承:子类不影响父类,子类可以继承父类的一些功能
属性的继承:调用父类的构造函数call
方法的继承: for in :拷贝继承(jquery也是采用拷贝继承extend)
<style> #div1{ 100px; height:100px; background:red; position:absolute;} #div2{ 100px; height:100px; background:yellow; position:absolute; left:100px;} </style> <script> window.onload=function(){ var d1=new Drag('div1'); d1.init(); var d2=new ChildDrag('div2'); d2.init(); } function Drag(id){ this.obj=document.getElementById(id); this.disX=0; this.disY=0; } Drag.prototype.init=function(){ var This=this; this.obj.onmousedown = function(ev){ var ev = ev || window.event; This.fnDown(ev); document.onmousemove = function(ev){ var ev = ev || window.event; This.fnMove(ev); }; document.onmouseup = function(){ This.fnUp(); }; return false; }; }; Drag.prototype.fnDown = function(ev){ this.disX = ev.clientX - this.obj.offsetLeft; this.disY = ev.clientY - this.obj.offsetTop; }; Drag.prototype.fnMove = function(ev){ this.obj.style.left = ev.clientX - this.disX + 'px'; this.obj.style.top = ev.clientY - this.disY + 'px'; }; Drag.prototype.fnUp = function(){ document.onmousemove = null; document.onmouseup = null; }; function ChildDrag(id){ //子类 Drag.call(this,id);//这个this指LimitDrag new的对象 } extend(ChildDrag.prototype,Drag.prototype);//实现继承父类方法 function extend(obj1,obj2){ for(var attr in obj2){ obj1[attr] = obj2[attr]; } } </script> </head> <body> <div id="div1"></div> <div id="div2"></div>
js没有类的概念,把JS中的构造函数看做类
要做属性和方法继承的时候要分开继承 类式继承
1 //类:JS是没有类概念的,把JS中的构造函数看做类 2 //类式继承:利用构造函数(类)继承的方式 3 function Aaa(){ 4 this.name=[1,2,3]; 5 } 6 Aaa.prototype.showName=function(){ 7 alert(this.name); 8 } 9 10 function Bbb(){ //子类 11 Aaa.call(this); 12 } 13 //这四句必须的 14 var F=function(){}; 15 F.prototype=Aaa.prototype; 16 Bbb.prototype=new F();//直接复制把所有东西度覆盖了 17 Bbb.prototype.constructor=Bbb; //修正指向问题 18 var b1=new Bbb(); 19 b1.name.push(4); 20 alert( b1.name );//1,2,3,4 21 var b2 = new Bbb(); 22 23 alert( b2.name );//1,2,3
原型继承
1 //原型继承: 无new的对象 2 var a={ 3 name:'小明' 4 }; 5 var b=cloneobj(a); 6 alert(b.name); 7 function cloneobj(obj){ 8 var F=function(){}; 9 F.prototype=obj; 10 return new F(); 11 }