JS面向对象:
面向对象:
--JS系统对象也是基于原型的程序
--不要修改或者添加系统对象下面的方法和属性
eg:
1 var arr = [1,2,3]; 2 Array.prototype.push = function() {}; 3 arr.push(4,5,6); 4 alert( arr );//1,2,3;push方法空无法添加 5 //push:方法的封装 6 var arr = [1,2,3]; 7 Array.prototype.push = function() { 8 for(var i=0;i<arguments.length;i++) { 9 this[this.length] = arguments[i]; 10 } 11 return this.length; 12 }; 13 arr.push(4,5,6); 14 alert( arr );
1.包装对象:基本的类型都有自己对应的包装对象:
String Number Boolean
Q1:str不是对象为何有一些方法?
字符串所对应的方法是在str的包装对象。
eg:
var str = 'hello';
str.chart(0);//基本类型会找到对应的包装对象,然后把包装对象的所有属性和方法给了基本类型,然后包装对象消失。
eg:
var str = 'hello';//基本类型
str.number = 10;
//在基本类型对应的包装类型下创建对象添加10,然后消失
alert(str.number);//undefined;str.number 又去创建对象,但找不到对应包装对象
2.原型链:
--实例对象与原型之间的链接(_proto_);
原型链的最外层是Object;
1 function Aa() {}; 2 Object.prototype.num = 30; 3 var a1 = new Aa(); 4 alert(a1.num);//30
3.面向对象的一些属性和方法:
1).hasOwnProperty:对象自身下的属性,是在Object下面的属性。...alert( arr.hasOwnProperty(num) == Object.prototype.hasOwnProperty );//ture
1 var arr = []; 2 arr.num = 10; 3 Array.prototype.num2 = 20; 4 alert( arr.hasOwnProperty(num) );//ture; 5 alert( arr.hasOwnProperty(num2) );//false;所有对象下的属性并不是arr下的属性
2).constructor:查看对象的构造函数
1 function Aa() {} 2 var a1 = new Aa(); 3 alert(a1.constructor);//函数
用来判断等:
var arr = [];
alert(arr.constructor == Array);//true;
如果写一个函数程序会自动添加一个原型的构造函数:Aaa.prototype.constructor = Aaa;
eg:
1 function Aa() {} 2 Aa.prototype.constructor = Array; 3 var a1 = new Aa(); 4 alert(a1.constructor);//弹出Array函数
但实际不要改。。。
不经意间会修改constructor
eg:
1 function Aa() {} 2 1/*Aa.prototype.name = "Wunworld"; 3 Aa.prototype.age = 23;*/ 4 5 2/*Aa.prototype = { 6 name : "Wunworld", 7 age : 23 8 }*/ 9 var a1 = new Aa(); 10 alert(a1.constructor); 11 //两种结果完全不一样:1弹出函数,2弹出的是对象Object的函数,赋值修改了constructor。如果采用第二种写法在对象中要添加constructor的指向。 12 Aa.prototype = { 13 constructor : Aa, 14 name : "Wunworld", 15 age : 23 16 }//这样不会修改。。
3)instancof:对象与构造函数在原型链上是否有关系(是不是在同一原型链上)
4)toString();系统对象下自带的,自己写的对象都是通过原型链找到Object下面的。
作用:1> 把对象转换成字符串
1 var arr = [1,2,3]; 2 alert(arr.toString());//"1,2,3" 3 4 var arr = [1,2,3]; 5 Array.prototype.toString = function(){ 6 return this.join("+"); 7 } 8 alert(arr.toString());//"1+2+3"
2> 数字进制的转换:
1 var num = 255; 2 alert(num.toString(16));//FF var num = 255; 3 alert(num.toString(16));//FF
3> 做类型判断
1 var arr = []; 2 alert(Object.prototype.toString.call(arr));[object Array] 3 4 alert(Object.prototype.toString.call(arr) == "[object Array]");//true
判断一个对象的方法(3中);
1 alert(arr.constructor == Array);//true 2 alert(arr intanceof Array);//true 3 alert(Object.prototype.toString.call(arr) == "[object Array]");//true
4.面向对象的继承:拷贝式继承
继承:在原有对象的基础之上,做一些修改,得到一个新的对象,不影响元有对象的功能。子类不影响父类,子类可以继承父类的一些功能,实现代码的复用。
属性的继承:调用父类的构造函数用.call改变this的指向。
方法的继承:父类的原型直接赋值(深赋值)该子类的原型,for in 拷贝继承
1 function CreatePerson(name,sex) {//父类 2 this.name = name; 3 this.sex = sex; 4 } 5 CreatePerson.prototype.showName = function() { 6 alert( this.name ); 7 } 8 var person1 = new CreatePerson("xiaoming","男"); 9 person.showName(); 10 11 function CreateStar(name,sex,job) {//子类 12 CreatePerson.call(this,name,sex);//this指向window前面没调用对象,用call改变this的指向。 13 this.job = job; 14 } 15 /*CreateStar.prototype = CreatePerson.prototype;*/ //引用类型,只要修改一个会影响另一个的值解决办法对象类型的深复制; 16 extend(CreateStar.prototype, CreatePerson.prototype);//调用对象深复制函数 17 var person2 = new CreatePerson("Wunworld","男","job"); 18 person2.showName();//继承过来了 19 20 function extend(obj1,obj2){ 21 for(var attr in obj2) { 22 obj1[attr] = obj2[attr]; 23 } 24 }
案例之面向对象demo;
HTML:
1 <style> 2 *{margin:0;padding:0;} 3 #div1{width:100px;height:100px;position: absolute;background:red;} 4 #div2{width:100px;height:100px;position: absolute;left:100px;background:yellow;} 5 </style> 6 </head> 7 <body> 8 <div id="div1"></div> 9 <div id="div2"></div> 10 </body>
1 function Drag(id) { 2 this.obj = document.getElementById(id); 3 this.disX = 0; 4 this.disY = 0; 5 } 6 Drag.prototype.init = function() { 7 var that = this; 8 this.obj.onmousedown = function(ev) { 9 var ev = ev || window.event; 10 that.FnDown(ev); 11 document.onmousemove = function(ev) { 12 var ev = ev || window.event; 13 that.FnMove(ev); 14 } 15 document.onmouseup = function() { 16 that.FnUp(); 17 } 18 return false; 19 } 20 } 21 Drag.prototype.FnDown = function(ev) { 22 this.disX = ev.clientX - this.obj.offsetLeft; 23 this.disY = ev.clientY = this.obj.offsetTop; 24 } 25 Drag.prototype.FnMove = function(ev) { 26 this.obj.style.left = ev.clientX - this.disX + "px"; 27 this.obj.style.top = ev.clientY - this.disY + "px"; 28 } 29 Drag.prototype.FnUp = function() { 30 document.onmousemove = null; 31 document.onmouseup = null 32 } 33 function ChildDrag(id){ 34 Drag.call(this,id);//属性的继承 35 } 36 extend(ChildDrag.prototype,Drag.prototype);//方法的继承 37 ChildDrag.prototype.FnMove = function(ev) {//方法的重写 38 var L = ev.clientX - this.disX; 39 var T = ev.clientY - this.disY; 40 if(L<0) { 41 L = 0; 42 }else if(L > document.documentElement.clientWidth - this.obj.offsetWidth) { 43 L = document.documentElement.clientWidth - this.obj.offsetWidth; 44 } 45 if(T < 0) { 46 T = 0; 47 }else if(T > document.documentElement.clientHeight - this.obj.offsetHeight) { 48 T = document.documentElement.clientHeight - this.obj.offsetHeight; 49 } 50 this.obj.style.left = L + "px"; 51 this.obj.style.top = T + "px"; 52 } 53 54 function extend(obj1,obj2){ 55 for(var attr in obj2){ 56 obj1[attr] = obj2[attr]; 57 } 58 } 59 60 var d1 = new Drag("div1"); 61 d1.init(); 62 var d2 = new ChildDrag("div2"); 63 d2.init();
5.继承的其他形式:
1).类式继承:利用构造函数继承
JS:是没有类的概念,把JS中的构造函数看作是类。属性和方法的继承要分开。
eg:
1 function Aa(){//父类 2 this.name = "Wunworld"; 3 } 4 Aa.prototype.showName(){ 5 alert(this.name); 6 } 7 function Bb(){}//子类 8 Bb.prototyppe = new Aa();//重点 9 Bb.prototype.constructor = Bb; 10 var b1 = new Bb(); 11 b1.showName();//子类继承了父类的方法和属性
通过创建父类的实例赋值给子类的原型,然后创建子类的实例,但这样做有问题,修改了b1的指向,alert(b1.constructor),时会弹出Aa();函数。所以在上述还要修改指向问题。
Bb.prototype.constructor = Bb;即可。但是,要区分开方法和属性的继承。
var F = function() {} F.prototype = Aa.prototype; Bb.prototyppe = new F();//重点 Bb.prototype.constructor = Bb;//以上是方法的继承
方法的继承原理:通过创建一个空构造函数,把父类的原型赋值给创建的构造函数的原型上,生成一个构造函数的实例赋值给子类的原型,再修改子类原型的构造指向即可。
子类的继承同样用 父类.call(this);
2).原型继承:借助原型来实现对象继承对象
eg:
1 var a = { 2 name : "Wunworld" 3 } 4 var b = cloneObj(a); 5 alert(b.name); 6 function cloneObj(obj) { 7 var F = function(){}; 8 F.prototype = obj; 9 return new F(); 10 }
原理:对象之间的继承,通过调用继承函数,继承函数的原理,利用空函数实现属性的赋值继承,通过原型链的访问实现继承。
三种继承的总结:
1.拷贝式继承:通用型,有没有new都可以使用
2.类式继承:利用new构造函数继承
3.原型继承:对象之间的继承