javascript面向对象

本文介绍了ES6中的类、构造函数、继承机制,包括如何创建类、使用`extends`实现继承,以及类中函数的使用和闭包与递归的概念。重点展示了类的实例化、构造函数与原型的应用,以及JavaScript中继承的两种方式:原型链和构造函数的结合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、特性

  1. 封装
  2. 继承
  3. 多态

二、ES6类

  1. 在es6中类没有变量提升,所以必须先定义类,才能通过类实例化方法
  2. 类里面所有的公用属性和方法一定要加this使用
1、es6创建类用到了class关键字
//# es6创建类用到class方法
//# 类名必须是大写字开头
//# 创建的类里面默认有一个构造函数是constructor函数,用于传递参数,返回实例对象
//# 只要new生成实例就会自动调用

 class Star {
 //constructor里面的this指向的是创建的实例对象ldh  
   constructor(name,age){
      this.name = name;
      this.age = age;
   }
   //1.我们类里面所有的函数都不需要写function关键字
   //2.多个函数方法之间不需要添加逗号分隔
   sing(song) {
   //sing里面的this指向的是创建的实例对象ldh  
	console.log(this.name+ song)
   }
 }
 
 //2、利用类创建实例对象 new
 var ldh = new Star('刘德华', 18);
 var zxy = new Star('张学友', 16);
 console.log(ldh.age);     //18
 console.log(zxy.age);     //16
 ldh.sing('冰雨');         //刘德华冰雨
 zxy.sing('李香兰');       //张学友李香兰
2、es6类里面继承使用关键字extends
 // 继承实例 Son 子类j继承Father父类
	class Father {
		constructor(x, y) {
			this.x = x;
			this.y = y;
		}
		money() {
			console.log(100);
		}
		sum() {
			console.log(this.x + this.y)
		}
	}
	
	//Son就继承了Father里面的属性和方法
	class Son extends Father {
		constructor(x, y) {
			//super调用父类的构造函数constructor
			//super 必须在子类this之前调取
			super(x, y);
			this.x = x;
			this.y = y
		}
		sum() {
		 //子类中调取父类的方法用也用super关键字
		  super.sum()   
		}
	}
	//1、继承中,如果子类中函数名和父类名字相同,先执行子类函数
	//2、如果想调取就用 super.函数名调取
	var son = new Son(1, 2);
	son.money();    //100
	son.sum();      //3
3、ES5中创建构造函数和原型
1、创建语法
   //1、创建构造函数
	function Star(name,age) {
	 //1、实例成员就是通过构造函数内部通过this创建的比如以下
	 //实例成员只能通过实例化对象来访问,不可以通过构造函数Star访问 
	  this.name = name;
	  this.age = age;
	  this.sing = function(){
	    console.log(this.name+ song)
	  }
	}
	
	//2、实例化对象
	var ldh = new Star('刘德华',18)
	ldh.sing()          //刘德华
	
   // 2、静态成员,在构造函数Star本身上添加的成员
   //  静态成员只能通过构造函数来访问
   Star.sex = '男';
   console.log(Star.sex);    //男
2、构造函数原型prototype
  • 1、 构造函数存在浪费内存问题,所以需要共享就会用到prototype
  • 2、javascript规定,每一个构造函数都有一个prototype属性,指向另一个对象,这个prototype本身也是一个对象。这个对象所有的属性和方法都会被构造函数所有
//Star()构造函数利用prototype添加dace方法
Star().prototype.dace= function() {
  console.log(100)
}
//使用dace方法
ldh.dace()         //100
3.对象原型 __proto__
 //实例化对象ldh身上系统自己添加一个__proto__指向我们构造函数的原型对象Star().prototype
 console.log(ldh.__proto__ == Star.prototype)   //ture
 //查找规则:先去构造函数里面查找,没有再去原型对象prototype上面查找
4、constructor属性
  • 1、对象原型 __proto__和原型对象prototype都有一个属性constructor,指回构造函数本身
  • 2、很多情况下,我们需要手动利用constructor这个属性,指回原来的构造函数
//里面也Star.prototype有一个__proto__对象,指向Object.prototype
//Object.prototype也有一个__proto__对象指向null(最顶级)
//原型链查找方式就近原则,先找本身,后找上级prototype
	function Star1() {

	}
	//正常使用不用constructor指回
	Star1().prototype.sing = function() {

	}
	Star1().prototype.song = function() {

	}
    //非正常使用,需要用constructor属性指回原来的构造函数
    Star1().prototype = {
        constructor:Star1,
	    sing:function() {
	
		}
    }
5、ES5继承
	//借用父构造函数的继承属性
	//父构造函数
	function Father1(username,ages){
		//this指向本身构造函数
		this.username = username;
		this.ages = ages;
	}
	Father1.prototype.exam ={
		
	}
	Son2.prototype = new Father1();
    //利用constructor指回,这样就继承了父构造函数
	Son2.prototype.constructor = Son;
	//子构造函数
	function Son2(username,ages){
		//this指向本身构造函数
		//利用call改变Father1构造函数的this指向
		Father1.call(this,username,ages);
	}
	var son = new Son('lm','20');
	console.log(son);

    	//bind 改变函数this指向
		//bind()方法, 不会调用原来的函数,可以改变原函数的this指向
		//2、返回的函数是this之后产生的新函数
		//3、如果有的函数我们不需要立即调用,但是又想改变原函数的this指向此时用bind
		var  o = {
			name:'12'
		}
		
		function fn(){
			
		}
		var f = fn.bind(o);
		console.log(f())
三、闭包和递归

		//闭包 一个作用域可以访问另一个函数内部的局部变量
		var car = (function(){
			var start = 13; //起步价
			var total = 0   //总价
			return {
				price:function(){
					return total;
				},
				yd:function(flag){
					return flag;
				}
			}
		})
		//定义的变量可以调用函数里面return返回的函数
		car.price();
		car.yd();
		
		//递归:函数内部自己调用自己
		//防止'栈溢出'  利用return可以退出
		function fn1(){
			fn1();
		}
		fn1();
		
		//浅拷贝和深拷贝
		//浅拷贝只拷贝最外层 ,深层次的会把地址拷贝过去比如sh
		Object.assign()
		var obj = {
			sh:{
				
			}
		}
		for (i in obj){
			
		}
		//深拷贝 函数递归
		function deepCopy(newobj,oldobj){
			//判断我们的属性是哪种数据类型
			//instanceof判断数据类型,数组Array必须放在前面因为数组也是object
			for (let k in oldobj) {
				let item = oldobj[k];
				if(item instanceof Array){
					newobj[k] = [];
					deepCopy(newobj[k],item);
				}else if(item instanceof Object){
					newobj[k] = {};
					deepCopy(newobj[k],item);
				}else{
					newobj[k] = item;
				}
			}
		}
		//正则
		 //   /^ $/g ^开头 $结尾 g全局匹配 i 不区分大小写
		 //   /abc/ 可以包含abc 检测为true
		 //   /[^abc]/ 取a、b、c任何一个为true  [^]这个里面的^是取反的意思
		 //   replace(/abc/g,'替换')  replace替换字符串
		 
		 //模板字符串
		 var a = 12
		 var str = `${a} 仲夏夜之梦`
		 console.log(str);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值