// 通过函数来创建对象,称为工厂模式:
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 createObj(age,name,sex){
var o=new Object
o.age=age
o.name=name
o.sex=sex
o.toString=function(){
return '我的名字'+o.name+'我的年龄'+o.age+'性别:'+o.sex
}
return o
}
wangsan=createObj(18,'wangsan','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属性查看自己的构造函数
//constructor 属性返回对创建此对象的数组函数的引用。
console.log(wanger.constructor)
console.log(wanger instanceof Person)
/*
构造函数的缺点:
构造函数方式主要是造成每个实例都会定义自己的方法,这样会占用更多的内存。
*/
构造函数用new创建的实例,访问属性中只能通过 实例+点+属性 的方式,不能直接写属性名。
构造函数的问题就是实例之间不能共享方法
函数对象原型Person.prototype
function Person(){
}
//这样的设定相当于重写了prototype
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())
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')
apply也是函数对象的一个方法
功能与call一样,不同的是参数传递方式
第一个参数是this指向的对象,第二个是参数数组
例如:Function.apply(obj,[args1,args2,…]
myFun.apply(o2,['sex'])
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="男"
}
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)
运行结果:
在javascript里,引用型属性是相互共享的,所以当lisi往family属性里添加一个son值时,zhangsan的family属性里也多了一个son的值,明显是不合理的,所以才会有原型继承的改进方法。
/*
改进引用型值在哥哥实力间共享的问题
*/
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')