重学js--面向对象(3)

概述

所有的函数都有prototype属性

function fn(){};
// fn.prototype ==> 内存地址 ==》存储一个对象
alert(fn.prototype instanceof Object)

闭包

使用闭包可以在全局作用域下访问局部变量
闭包的优缺点:

优点:可以访问局部变量,封装性好
缺点:使得局部变量一直在内存中,内存消耗大

function fn1(){
	var a=1;
	function fn2(){
		// 在这里可以访问局部变量a
		a++;
	}
	// 将fn2返回出去,也就是将a变量反出去
	return fn2;
}
var fn = fn1() //fn2
fn() //执行了fn2,在作用域外修改了局部变量a

对象的声明

字面式声明
var person={
	name:'zhangsan',
	age: 26,
	sex:'man',
	eat:function(fds){
		aleart('我在吃'+fds)
	}
}
person.eat('面条')
new操作符后跟Object构造函数
var person=new Object();
person.name='zhangsan';
person.age=26;
person.sex='man';
person.eat=function(fds){
	// this 指向当前对象
	aleart(this.name + '在吃'+fds) 
};

person.eat('面条')
js中构造方法声明对象
function Person(name,age,sex){
	this.name=name;
	this.age=age;
	this.sex=sex;
	this.eat=function(str){
		alert(this.name+'在吃'+str)
	}
} 
// this指向当前实例化对象
// this指向person1
var person1=new Person('xm',26,'nan');
person1.eat('面条');

// this指向person2
var person2=new Person('xh',26,'wonan');
person1.eat('饺子')
js中工厂方式声明对象
function createObject(name,age,sex){
	var obj=new Object();
	obj.name=name;
	obj.age=age;
	obj.sex=sex;
	obj.show=function(){
		console.log(this.name+this.age+this.sex)
	}
	return obj;
}
// 工厂模式在使用的时候不需要new
var p1=createObject('xh',26,'nan');
var p2=createObject('xm',28,'nan');

构造方式和工厂模式的不同:

  1. 构造方式不会显示创建对象,将属性都赋值给了this,不需要return对象;
  2. 工厂模式必须在方法内部创建object对象,并返回它,属性和方法都是赋值给object对象
js中原型模式声明对象

任何js方法或函数,都自带一个prototype属性,且它以对象方式存在。

function person(){}
person.prototype.name='zhangsan';
person.prototype.age=26;
person.prototype.sex='男';
person.prototype.show=function(){
	console.log(this.name+this.sex+this.age)
}
var p1=new person();

// 还可以以json数据定义属性和方法
person.prototype={
	name:'zhangsan',
	age:26,
	sex:'男',
	show:function(){
		console.log(this.name+this.sex+this.age)
	}
}
js中混合模式声明对象: 构造+原型
function person(name,age,sex){
	this.name=name;
	this.age = age;
	this.sex = sex;
}
person.prototype.show=function(){
	console.log(this.name+this.sex+this.age)
}
var p1=new person('xh',18,'nan');

对象遍历及存储

遍历对象的属性及方法
var ren = {};
ren.name='xh';
ren.age=18;
ren.sex='男‘;
ren.demo=function(){
	document.write('aaa');
}
// 遍历
for(var key in ren){
	aleart(ren[key])
}
对象在内存中的分布

在这里插入图片描述

封装

  • 把对象内部数据和操作细节隐藏起来;
  • js中可以通过闭包实现封装

原型和原型链

原型:是利用prototype添加属性和方法
原型链:JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的函数对象的原型对象prototype

var person=function(){};
var p = new person();
// new实例化对象经历了以下三部
// 1.创建对象:var p={};
// 2.将实例的原型链指向构造函数的prototpye原型:p.__proto__=person.prototype
// 3.初始化对象:p==》person.call(p)

原型链实现过程

var fn=new fn2();
上面的一句话实现了: fn.proto=fn2.prototype

fn2.prototype=new fn1();
上面一句话实现了:fn2.prototype=fn1.prototype
然后 fn.proto=fn2.prototype=fn1.prototype
fn也就有了fn1和fn2原型上的属性和方法

var fn1=function(){};
fn1.prototype.demo1=function(){
	alert('我是fn1'};
}
fn1.prototype.a=500;

var fn2=function(){};
fn2.prototype=new fn1();
fn2.prototype.demo2=function(){
	alert('我是fn2'};
}
fn2.prototype.a=1000;

var fn=new fn2();
fn.demo2();
fn.demo1();
fn.a  //1000 子类上的属性会将父类上的属性覆盖掉

原型继承

function Person(name,age,sex){
	this.name=name;
	this.age=age;
	this.sex=sex;
};
Person.prototype.say=function(){
	aleart('你好')
}

function Student(){};
// 原型继承
Student.prototype=new Person();
Student.prototype.gran=function(){
	print('年纪')
}

var s=new Student();
s.say();
// 过程解析:
// 1. 现在s上找say方法,s实例上没有就在s.__proto__属性上找,该属性指向的是Student.prototype原型
// 2. Student.prototype原型原型等于new Person(),也就是将__proto__属性指向了Person.prototype,然后在Person.prototype上找到了say方法;

构造函数的继承

function Parent(name){
	this.name=name;
	this.say=function(){
		console.log('我是父类')
	}
}

function Child(name,age){
	//继承父类
	this.pObj=Parent;
	// 给父类传参数
	this.pObj(name);
	
	this.age=age;
	this.sayC=function(){
		console.log('我是子类')
	}
}
var p=new Parent('xh');
p.say();

var c=new Child('xm',18);
c.sayC()
  • call、apply实现继承
function Person(name,age,sex){
	this.name=name;
	this.age=age;
	this.sex=sex;
	this.show=function(){
		aleart(this.name+':'+this.age+':'+this.sex)
	}
}

// call实现继承
function Student(name,age){
	// this指向Student
	Person.call(this,name,age)
}

// apply实现继承
function Teacher(name,age,sex){
	Person.apply(this,[name,age,sex])
}

var p=new Person('人类',18,'男');
p.show();

var s=new Student('学生',18);
s.show();

var t=new Teacher('老师',28,'女')
t.show()

js面向对象的关键词

instanceof

判断变量是否是对象的实例

function test(){};
var fn=new test();
// 判断fn是否是test的实例
console.log(fn instanceof test) //true
console.log(fn instanceof Object) //true
delete

删除对象的属性,不可以删除方法;
删除不了变量和原型链上的属性;

function fun(){
	this.name='xh';
	this.say=function(){
		alert(this.name)
	}
}
var fn=new fun();
fn.say();
delete fn.name;
fn.say();
call,apply
function add(a,b){
	alert(a+b);
}
function sub(a,b){
	alert(a-b);
}
// add 替换 括号中的sub,所以执行a+b
// 括号中的sub位置必须指向存在的对象
add.call(sub,5,3) //5+3=8
function animal(){
	this.name='animal';
	this.showName=function(){
		alert(this.name);
	}
}
function cat(){
	this.name='cat';
}
var an=new animal();
var c=new cat();
// an.showName.call(c,'');
an.showName.apply(c,[]);
arguments
  • arguments.length
  • arguments[index]
callee
  • 返回正在执行的function对象,function内容;
  • 它是arguments的属性:arguments.callee;
  • 默认值:正在执行的function对象
  • callee就是指代函数本身
function demo(){
	// 弹出整个函数本身
	alert(arguments.callee);
	
	// 报错:循环执行本函数,造成死循环
	alert(arguments.callee());
}


// 可以使用callee进行回调
function sum(n){
	if(n<=1) return;
	return n+arguments.callee(n-1)
}
alert(sum(5))
this
  • 可以在函数内部定义属性/变量
function test(){
	this.x=1; //this 全局变量 等同于x=1
}
  • 作为方法调用 构造函数内this指当前实例对象
function Test(){
	this.name='xh';
	this.age=18;
}
// this指代当前实例t
var t=new Test();
t,name
  • 在apply、call中
var x=0;
function test(){
	alert(this.x);
}
var o={};
o.x=1;
o.m=test;
// apply中没有传递参数,默认指向window,所以弹出全部变量x的值
o.m.apply(); //0
// 指向o
o.m.apply(o); //1

对象冒充

将父类的属性和方法一起传给子类作为特权属性和特权方法

function paren(name,age){
	this.name=name;
	this.age=age;
	this.say=function(){
		alert('说话')
	}
}
parent.prototype.walk=function(){
	alert('走了吧')
}

function student(name,age,sex){
	this.obj=paren; //冒充paren
	this.obj(name,age);
	this.sex=sex;
}
var s=new student('xh',18,'男');
s.say(); //继承了
s.walk(); //报错
// s继承了paren中的特权属性和方法,没有继承共有属性和方法
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的公寓报修管理系统,源码+数据库+毕业论文+视频演示 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本公寓报修管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此公寓报修管理系统利用当下成熟完善的Spring Boot框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的MySQL数据库进行程序开发。公寓报修管理系统有管理员,住户,维修人员。管理员可以管理住户信息和维修人员信息,可以审核维修人员的请假信息,住户可以申请维修,可以对维修结果评价,维修人员负责住户提交的维修信息,也可以请假。公寓报修管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 关键词:公寓报修管理系统;Spring Boot框架;MySQL;自动化;VUE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值