工厂模式
- 通过函数来创建对象,称为工厂模式
- 工厂模式的缺点:创建对象没有特定类型
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")
![]()
构造函数模式
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)
![]()
原型模式
- 实例之间不能共享方法
- 函数对象原型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")
apply与call
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
/*
call是函数对象的一个方法
通过call可以指定函数内部的this对象
第一个参数是this指向的对象,后面通过逗号分隔传递多个参数
例如:Function.call(obj,args1,args2,args3...)
*/
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(o2,"name")
myFun.call(o2,"sex")
/*apply也是是函数对象的一个方法
功能与call一样,不同的是参数传递方式
第一个参数是this指向的对象,第二个是参数数组
例如:Function.apply(obj, [args1,arg2,…])
*/
myFun.apply(o1, ["sex"])
myFun.apply(o2, ["sex"])
</script>
</body>
</html>
原型继承
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
// 父类构造函数
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)
</script>
</body>
</html>
原型继承改进方式
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
// 改进引用类型值在各个实例共享的问题
function Person(name,age,sex,family) {
this.hands = 2
this.legs = 2
this.family = family
this.say = function(){
console.log("my name is "+this.family)
}
}
//将原型指向到Person,即可继承
Man.prototype = new Person()
//子对象结构函数
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,[])
}
wangwu = new Man("wangwu", 58)
wangwu.family.push("father")
lisi = new Man("lisi", 28)
lisi.family.push("wife")
// console.log(lisi.family)</script>
</body>
</html>
- 定义一个车的构造函数,然后再定义汽车,自行车的构造函数,汽车与自行车主要是动力不同,轮子数量不一样
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
// 定义一个车的构造函数,然后再定义汽车,自行车的构造函数,汽车与自行车主要是动力不同,轮子数量不一样
function Vehicle(){
}
Vehicle.prototype.move = function(){
console.log("move speed",this.speed)
}
function Car(power){
Car.prototype.constructor.call(this)
this.wheel = 4
this.speed = 100
}
Car.prototype = new Vehicle()
function Bike(power){
Bike.prototype.constructor.call(this)
this.wheel = 2
this.speed = 40
}
Bike.prototype = new Vehicle()
var car = new Car()
var bicycle = new Bike()
</script>
</body>
</html>
![]()