JS学习日记--面向对象

一、js面向对象

1.什么是面向对象

   面向对象编程(OOP)是一种计算机编程架构,他将真实世界的各种复杂的关系,抽象为一个个对象,然后由对象之间的分工与合作,完成对真实世界的模拟

2.面向对象的目的

  • 重用性:针对相同的功能可以重复的使用程序
  • 灵活性:针对差异性的功能做出适配与调整
  • 扩展性:针对功能的变化做出添加或删除的改进

3.面向对象的特性

  • 封装性:封装是一种信息隐蔽技术,使得用户只能见到用户的外特性,而对象的内特性对用户是隐蔽的,封装的目的在于把对象的设计者和对象的使用者分开,使用者不必知晓实现的细节,只需用设计者提供的消息来访问该对象
  • 继承性:复用一些原有的功能,同时可修改和扩充
  • 多态性:对象根据所接收的消息而做出动作,同一消息为不同的对象接收时可产生完全不同的行动

4.面向对象的组成

  • 属性:描述一种状态
  • 方法:描述一种行为
  • 程序中变量就是属性,函数就是方法

5.创建面向对象程序

在面向对象编程中,是通过“类”来创建对象的,类相当于模具。根据传递的数据来创建对象,并且可以重复的创建对象
   在ES6之前的JavaScript中,是没有类的概念的,不过可以利用构造哈数来代替类进行创建对象
   构造函数跟普通的函数并没有太大区别,知识调用的时候需要通过new关键字来调用,构造哈数中的this会指向创建出来的对象,并且具有隐式返回

示例代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		
		<script type="text/javascript">
			function fun(name){
				this.name=name;
				this.showName=function(){
					console.log(this.name);
				}
			}
			
			
			var obj=new fun('hi');
			var obj1=new fun('hello');
			obj.showName();
			obj1.showName();
		</script>
	</head>
	<body>
	</body>
</html>

二、object对象详解

1.对象的引用

  • 类型比较方式:对象比较时,值跟引用地址都相同时才相等
		   var obj1={};
		   var obj2={};
		   console.log(obj1==obj2);
输出为:false
  • 类型赋值方式:对象赋值时,值跟引用地址都进行赋值操作
		   var obj={
			   name:'hello'
		   }
		   var obj2=obj;
		   obj2.name='hi';
		   console.log(obj.name)
输出为:hi
赋值时把obj的地址也赋给了obj2
  • 浅拷贝与深拷贝:实现对对象的复制操作
    浅拷贝:
		   var obj={
		   			   name:'hello'
		   }
		   var obj2=copy(obj);
		   function copy(obj){//浅拷贝
			   var result={};
			   for(var attr in obj){
				   result[attr]=obj[attr];
			   }
			   return result;
		   }
		   obj2.name='hi';
		  console.log(obj.name) ;
通过这个就可以只实现对象值得赋值而不会改变原有对象,不过如果对象的属性也是一个对象,就需要深拷贝

利用递归进行深拷贝:

var obj={
		     			   name:{age:20}
		     }
		     var obj2=copy(obj);
		     function copy(obj){//深拷贝
		   			   var result={};
		   			   for(var attr in obj){
						   if(typeof obj[attr]=='object'){
							   result[attr]=copy(obj[attr]);//递归
						   }else{
							   
		   				   result[attr]=obj[attr];
						   }
		   			   }
		   			   return result;
		     }
		     obj2.name.age=30;
		    console.log(obj.name.age) ;
			

2.原型与原型链

  • 原型:
    在构造函数下面有一个prototype属性叫做原型,构造函数+原型整体也是一个对象叫做原型对象,在原型对象下面可以添加属性和方法
  • 共享:
    原型对象下的属性和方法,可供多个对象进行共享访问,这样就可以节省内存消耗(因为这样用的是一个地址,而上面咱们写的,每一个对象的方法都是不同的地址)
		function Foo(name){
			this.name=name;

		}
		Foo.prototype.showName=function()
		{
				console.log(this.name)
			
		}
		var obj=new Foo('hello');
		var obj2=new Foo('hi');
		console.log(obj.showName==obj2.showName);
输出结果:true
证明用的是同一个地址
  • 原型链:
    为什么创建出来的对象可以访问到原型对象下面的属性和方法呢?这是通过哦原型链进行查找的。原型链即:连接对象与原型对象之间的纽带就是原型链
    【注】:原型链最外层是Object.prototype,可以通过控制台查看

3.面相对象相关语法

  • constructor:原型对象下唯一默认自带的属性,用于查看对象的构造函数
  • instanceof:左边是实例对象,右边是构造函数,他会检查右边构造函数的原型对象,是否在左边对象的原型链上
  • in与for…in:in运算返回一个布尔值,表示一个对象是否具有某个属性。for…in循环可获得对象所有可枚举属性
    示例代码:
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>相关语法</title>
	<script type="text/javascript">
		
	/*	function Foo(){
			
		}
		//Foo.prototype.constructor=Foo; 
	Foo.prototype={
		constructor:Foo
		showName:function(){}
	};
		var obj=new Foo();
		console.log(obj.constructor);//Foo(){}
		*/
	/*   function Foo(){
		   
	   }
	var obj=new Foo();
	console.log(obj instanceof Foo);//true
	*/
   function Foo(){
	   this.name='hello'
   }
	var obj=new Foo();
	console.log('name' in obj);//true
	console.log('age' in obj);//false
	
	
	
	</script>
	</head>
	<body>
	</body>
</html>

4.系统对象与包装对象

  • 系统对象:JavaScript语言本身就是基于面向对象的程序,最大的对象为window对象。内置了很多系统对象,如:数组、时间、正则等。
    可以自行打印一下window对象,可以看到很对内置的对象

仔细想想其实JS本身就是一个很大的面向对象的程序,包括我们平时用的数组之类的都是一个对象,有push,sort等方法

首先,假如我们进行了这样的操作

		<script type="text/javascript">
			var arr=[1,2,3];
			Array.prototype.push=function(){
				
			}
			arr.push(4,5,6)
			console.log(arr);
		</script>
	</head>
这样push操作就会失败,因为我们重写了数组对象的push方法,也验证了上面说的,数组就是一个对象

接下来咱们自己实现一个push方法:

		<script type="text/javascript">
			var arr=[1,2,3];
			Array.prototype.push=function(){
				for(var i=0;i<arguments.length;i++){
					this[this.length]=arguments[i];
				}
				return this.length;
			}
			arr.push(4,5,6)
			console.log(arr);
		</script>
	</head>
  • 包装对象:基本类型如:字符串、数字、布尔值等都具备对应的包装对象。可以通过包装对象来获取提供的属性与方法
    如:字符串其实就是new String创造出来的包装对象
    当我们用字符串的一下方法比如 str.trim()时,他其实是先找到new String()对象,再找到trim方法,他写在原型链上共享给了str

5.继承与多态

(1)继承方式

拷贝继承:
		<script type="text/javascript">
			function Foo(){//父类
				this.name='hello';
			}
			Foo.prototype.showName=function(){
				console.log(this.name);
			};
			function Bar(){//子类
				Foo.call(this);
				this.age=20
			}
			extend(Bar,Foo);
			Bar.prototype.showAge=function(){
				console.log(this.age);
			}
			function extend(subs,sups){
				for (var attr in sups.prototype) {
					subs.prototype[attr]=sups.prototype[attr];
				}
			}
			var obj1=new Foo();
			var obj2=new Bar();
			console.log(obj1);
			console.log(obj2);
		</script>
类式继承:
		<script type="text/javascript">
			function Foo(){//父类
				this.name='hello';
			}
			Foo.prototype.showName=function(){
				console.log(this.name);
			};
			function Bar(){//子类
				Foo.call(this);//继承属性还是用call
				this.age=20
			}
			extend(Bar,Foo);
			Bar.prototype.showAge=function(){
				console.log(this.age);
			}
			/*function extend(subs,sups){
				for (var attr in sups.prototype) {
					subs.prototype[attr]=sups.prototype[attr];
				}
			}*/
			function extend(subs,sups){
				//不直接用原型链继承而是通过新建一个函数实现只继承方法
				//否则创造多个对象之后可能就会影响到这个属性
				var F=function(){};
				F.prototype=sups.prototype;
				subs.prototype=new F();
				subs.prototype.constructor=subs;//修改了原型之后要把,constructor修正一下
			}
			var obj1=new Foo();
			var obj2=new Bar();
			console.log(obj1);
			console.log(obj2);
		</script>

(2)多态

重写继承的方法

就是简单的重写一下方法,例如上面的例子,咱们把Bar的showName方法重写一下

			Bar.prototype.showName=function(){
				console.log('aaa'+this.name);			
				}

接下来调用Bar.showName()就会输出aaahello

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值