面相对象(二)

原型链:实例对象与原型之间的连接,叫做原型链

原型链的最外层 : 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 }
日常所遇,随手而记。
原文地址:https://www.cnblogs.com/zhihou/p/8108737.html