Python学习笔记:5.2.5 javascript面向对象

本文是学习陆老师的《python全栈工程师 - web开发前端基础》课程的笔记,欢迎学习交流。同时感谢陆老师的精彩传授!

一、课程目标
  • 工厂模式
  • 构造函数模式
  • 原型模式
二、详情解读
2.0.引用类型练习

练习1:
请创建一个函数,可以根据输入不同的姓名,年龄、性别,创建不同的用户实例

function createUser(name, age, sex){
	var  o = new Object()
	o.name = name
	o.age  = age
	o.sex  = sex
	o.toString = function(){
		return "我的名字" + o.name + "我的年龄:"+o.age + "性别:" + o.sex
	}
	return o
}
wangsan = createUser("wangsan", 18, "girl")
console.log(wangsan)

运行结果:
在这里插入图片描述

练习2:
写一个copy对象的函数,实现两个对象之间值相等,但不是同一个对象,比如 obj2拷贝obj1中的每一项,但是obj1的修改不影响obj2(浅拷贝与深拷贝)

function copyObject(object){
   var o = new Object()
   for (i in object){
   	// 深拷贝
	  /* if (typeof(object[i]) == "object"){
		   o[i] = copyObject(object[i])
	   } else {
		   o[i] = object[i]
	   } */
	   // 浅拷贝
		o[i] = object[i]
   }
   return o
}
var obj = new Object()
obj.name = {first:"luxp", last:"pp"}
obj.age = 18

深拷贝运行结果:(当obj的name.first属性改变时,obj_2的name.first属性没有变化)
在这里插入图片描述
浅拷贝运行结果:(obj的属性改变,obj_2的也发生改变)
在这里插入图片描述

练习3:
系统有这么一些商品:(洗衣机,3000元), (笔记本电脑,12000元),(音箱,1000),请使用合适的方式表示这一组商品

goods = []
goods[0] = ["洗衣机",3000],
goods[1] = {"笔记本电脑":12000}
goods[2] = {"音箱": 1000}

练习4:
实现一个FIFO队列对象,只有两个方法put(向队列写入数据)与 get(从队列中读取数据)

var queue = new Object()
   queue.data = []
   queue.put = function(val){
	  queue.data.push(val)
   }
   queue.get = function(){
	  return queue.data.shift()
   }

练习5:
[{“name”:“luxp”},{“name”:“wangsan”}, {“name”:“ls”}, {“name”:“ns”} ]
使用sort按照name的值排序

array = [{"name":"luxp"},{"name":"wangsan"}, {"name":"ls"}, {"name":"ns"} ]
function compare(val1,val2){
   if (val1.name > val2.name){
	   return true
   } else {
	   return false
   }
}
sorted_array = array.sort(compare)

练习6:
使用filter 挑出 5的倍数

array = [1,3,5,8,10,15] 
new_array = array.filter(function(val){
   if (val%5==0){
	   return true
   }
   
})

练习7:
有这么一份商品价格数据
[“商品名称”,商品价格,销售额]
[[“good1”,1000,5000],[“good2”,1200,3600],[“good3”,1500,6000],
[“good4”,1000,2000],[“good5”,1300,5200],[“good6”,1400,5600]]
统计一下,价格在1200以上(不包含1200)的商品销售总额

array = [["good1",1000,5000],["good2",1200,3600],["good3",1500,6000],
["good4",1000,2000],["good5",1300,5200],["good6",1400,5600]]

function compare(pre,cur){
  console.log("cur",cur,cur[0])
  if (cur[1]>1200){
	  return pre+cur[2]
  } else {
	  return pre
  }
  
}
res = array.reduce(compare, 0)

运行结果:
在这里插入图片描述

** 练习8:
找出往后500年的闰年,并console中输出出来
闰年计算方法:
普通年能被4整除且不能被100整除的为闰年
世纪年能被400整除的是闰年。(如2000年是闰年,1900年不是闰年)**

 date = new Date()
 year = date.getFullYear()
 for (i=0;i<=500; i++,year++){
	if (year%4==0 && year%100!=0){
		console.log(year) 
	}
	if (year%100==0 && year%400==0){
		console.log(year)
	}
 }

运行结果:
在这里插入图片描述

练习九:
注册用户要求: 不能含有kefu, kf,admin等字符,并且以任意英文字母开头,包含英文或者数字,
最短不能少于5个字符,最长不能超过15个字符,写一个用户输入验证函数

reg1 = new RegExp("^[a-z]\\w{4,14}$")
reg2 = new RegExp("(kf)|(kefu)|(admin)")
function validateUserName(user_name){
	if (!reg1.test(user_name)){
		return false
	}
	if (reg2.test(user_name)){
		return false
	}
	return true
}
2.1.工厂模式
// 通过函数来创建对象,称为工厂模式:
function createObj(id, name, val) {
	var o = new Object()
	o.id = id
	o.name = name
	o.val = val
	return o
}
o1 = createObj(1, 'first', 10)
o2 = createObj(2, 'second', 20)

工厂模式的缺点:创建对象没有特定类型

代码示例:

function createUser(name, age, sex){
	var  o = new Object()
	o.name = name
	o.age  = age
	o.sex  = sex
	o.toString = function(){
		return "我的名字" + o.name + "我的年龄:"+o.age + "性别:" + o.sex
	}
	return o
}
wangsan = createUser("wangsan", 18, "girl")
2.2.构造函数模式
function Person(name, age, sex) {
	this.name = name
	this.age = age
	this.sex = sex
}

wangSan = new Person('wang san', 18, 'man')
cuihua = new Person('cuihua', 20, 'woman')

通过构造函数模式,可以创建自己的类型
构造函数是通过new关键字创建函数实例对象

代码示例:


function Person(name, age, sex) {
	this.name = name
	this.age  = age
	this.sex  = sex
	this.getName = function(){
		console.log(this.name)
	}
}
// o = Person("wanger", 18, "girl")
wanger   = new Person("wanger", 18, "girl")
zhangsan = new Person("zhangsan", 28, "boy")

//可以通过实例的constructor属性查看自己的构造函数
console.log(wanger.constructor)
console.log(wanger instanceof Person)

/* 
构造函数的缺点:
 构造函数方式主要是造成每个实例都会定义自己的方法,这样会占用更多的内存
 */
// console.log(wanger.getName)
// console.log(zhangsan.getName)

/* 
 两个实例相同的方法并不是同一个对象
 */
console.log(wanger.getName == zhangsan.getName)

运行结果:
(构造函数用new创建的实例,访问属性中只能通过
”实例+点+属性“的方式,不能直接写属性名)
在这里插入图片描述
在这里插入图片描述

2.3.原型模式

构造函数的问题就是实例之间不能共享方法
函数对象原型Person.prototype

function Person(){
	
}
Person.prototype = {
	hello:function(){
		console.log("hello")
		console.log(this.name)
	}
}
person_1 = new Person()
person_2 = new Person()

person_1.name = "luxp"
person_2.name = "lisi"

person_1.hello()
person_2.hello()

function Person(name, age, sex) {
	this.name = name
	this.age  = age
	this.sex  = sex
	this.family = []
	this.say = function(){
		console.log("my name is "+this.name)
	}
}

wanger   = new Person("wanger", 18, "girl")
zhangsan = new Person("zhangsan", 28, "boy")

// 在原型上添加一个方法{}

Person.prototype.getName = function(){
	console.log(this.name)
}


console.log(wanger.say == zhangsan.say)
//还可以增加共同的属性 - 相当于python的类属性

Person.prototype.hands = 2
console.log(wanger.hands)

Person.prototype.getSex = function(){
	console.log(this.sex)
}

console.log(wanger.getSex())

//
//这样设定,等于重写了prototype

Person.prototype = {
	"getAge":function (){
		console.log(this.age)
	}
}

lisi = new Person("lisi", 38, "boy")
2.3.1.apply与call

call是函数对象的一个方法
通过call 可以指定函数内部的this对象
第一个参数是this指向的对象,后面通过逗号分隔传递多个参数
例如:Function.call(obj, args1,arg2,…)

function myFun(property){
	console.log(this)
	console.log(this.name)
	console.log(this[property])
}

var o1 = {
   name:"luxp",
   sex : "男"
}
		
var o2 = {
   name:"whh",
   sex : "女"
}

myFun.call(o1, "sex")
// myFun.call(o2, "sex")

运行结果:
在这里插入图片描述

apply也是是函数对象的一个方法
功能与call一样,不同的是参数传递方式
第一个参数是this指向的对象,第二个是参数数组
例如:Function.apply(obj, [args1,arg2,…])

myFun.apply(o1, ["sex"])
// myFun.apply(o2, ["sex"])

运行结果:
在这里插入图片描述

2.3.1.原型继承
function Person(name, age, sex) {
	this.hands = 2
	this.legs  = 2
	this.family  = []
	this.say = function(){
		console.log("my name is "+this.name)
	}
}

//子对象结构函数
function Man(name, age){
	this.name = name
	this.age  = age
	this.sex = "男"
	
}

//将原型指向到Person,即可继承
Man.prototype = new Person()

//重写原型方法
Man.prototype.say = function(){
		console.log("welcome to here")
	}

// 
wangwu = new Man("wangwu", 58)
zhangsan = new Man("zhangsan", 28)


function WoMan(name, age){
	this.name = name
	this.age  = age
	this.sex  = "女"
}

//将原型指向到Person
WoMan.prototype = new Person()
//重写原型方法
WoMan.prototype.say = function(){
	console.log("hi,what can i do for you?")
}


cuihua = new WoMan("cuihua", 18)

/* 
 添加家庭成员
 */
wangwu.family.push("whife")

/* 
 尴尬的事情,同一个Man的对象,引用型属性是相互共享的
 */
lisi = new Man("lisi", 28)
lisi.family.push("son")
// console.log(lisi.family)

运行结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在js里,引用型属性是相互共享的,所以当lisi往family属性里添加一个son值时,zhangsan的family属性里也多了一个son的值,明显这是不合理的,所以才会有原型继承的改进方法,看下一小节内容

在这里插入图片描述

2.3.2.原型继承改进
/* 
 改进引用型值在各个实例间共享的问题
 */
function Person(name, age, sex,family) {
	this.name = name
	this.age  = age
	this.sex  = sex
	this.family = family
	this.say = function(){
		console.log("my family has "+this.family)
	}
}

function Man(name, age, sex){
	console.log(Man.prototype)
	console.log(Man.prototype.constructor)
	//相当于python的super()执行
	// Person.call
	Man.prototype.constructor.call(this, name, age, sex, [])
}

Man.prototype = new Person()
wangwu = new Man("wangwu", 58)
wangwu.family.push("father")
lisi = new Man("lisi", 38)
lisi.family.push("wife")

在这里插入图片描述

练习1:
定义一个车的构造函数,然后再定义汽车,自行车的构造函数,汽车与自行车主要是动力不同,
轮子数量不一样

三、课程小结
  • 学习了js的工厂模式
  • 学习了js的构造函数
  • 学习了js的原型模式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值