先看几种常用的定义方式:
function func1([参数]){
/*函数体*/
}
var func2=function([参数]){
/*函数体*/
}
var func3=function func4([参数]){
/*函数体*/
}
var func5=new Function()
上述第一种方式是最常用的方式,不用多说。
第二种是将一匿名函数赋给一个变量,调用方法:func2([函数])
第三种是将func4赋给变量func3,调用方法:func3([函数])或func4([函数])
第四种是声明func5为一个对象。
再看看它们的区别:
function func(){
//函数体
}
//等价于
var func=function(){
//函数体
}
但同样是定义函数,在用法上有一定的区别。
<script>
//这样是正确的
func(1)
function func(a)
{
alert(a)
}
</script>
<script>
//这样是错误的,会提示func未定义,主要是在调用func之前没有定义
func(1)
var func = function(a)
{
alert(a)
}
//这样是正确的,在调用func之前有定义
var func = function(a)
{
alert(a)
}
func(1)
</script>
用同样的方法可以去理解第三种定义方式。
第四种定义方式也是需要声明对象后才可以引用。
代码:
a={val:9,
fc:function(){
alert('1')
}
}
调用a.fc()
原理:
js是弱语言,相对来说语法比较宽松,主要掌握常用的三个对象,函数(function),数组(array或[]定义),对象({}方式定义)。这三者是可以相互组合的,上面也就是一个组合。
比如:var k=[
{m1:'2'},
{m2:function(){}}
]
这个例子就是数组包含对象,对象包含函数。
Javascript对象定义的几种方式一.工厂方式:先创建对象,再向对象添加方法和属性,封闭后调用不要使用new操作符创建对象。使用这种方法有很多弊端,把方法定义在工厂函数内部的时候,每次调用的时候都会产生新的函数
function factory(name,person,address,time){
var tmp=new Object
tmp.name=name
tmp.person=person
tmp.address=address
tmp.workTime=function(){
alert("we start to work at" + time)
}
return tmp
}
var factory1=factory("drugs",100,"huashan Rd",10)
var factory2=factory("TCMdrugs",100,"hongqiao Rd",11)
factory1.workTime()
factory2.workTime()//Here,factory1 and factory2 have different method
对这种问题虽然可以用下面的方式改进,但是缺乏很好的封装性
function factory(name,person,address,time){
var tmp=new Object
tmp.name=name
tmp.person=person
tmp.address=address
tmp.workTime=workTime()
return tmp
}
function workTime(){
alert("we start to work at" + this.time)
}
二,构造函数方式,在构造函数内部不创建对象,使用this关键字,使用时候用new操作符,存在和工厂方式相同的问题,重复创建函数。
function counstruct(name,person,address,time){
this.name=name
this.person=person
this.address=address
this.workTime=function(){
alert("we start to work at" + this.time)
}
}
三.原型方式:利用prototype属性来实现属性和方法,可以通过instanceof 检查对象类型,解决了重复创建函数的问题,但不能通过传递参数初始化属性
function Car(){
}
Car.prototype.color = "red"
Car.prototype.doors = 4
Car.prototype.mpg = 23
Car.prototype.showColor = function(){
alert(this.color)
}
var car1 = new Car()
var car2 = new Car()
但是如果遇到下面的情况,又出问题了
Car.prototype.drivers = new Array("mike", "sue")
car1.drivers.push("matt")
alert(car1.drivers) //outputs "mike,sue,matt"
alert(car2.drivers) //outputs "mike,sue,matt"
drivers是指向Array对象的指针,Car的两个实例都指向同一个数组。
四.混合的构造函数/原型方式:针对原型方式的解决方案
function Car(sColor, iDoors, iMpg){
this.color = sColor
this.doors = iDoors
this.mpg = iMpg
this.drivers = new Array("mike", "sue")
}
Car.prototype.showColor = function (){
alert(this.color)
}
var car1 = new Car("red", 4, 23)
var car2 = new Car("blue", 3, 25)
car1.drivers.push("matt")
alert(car1.drivers)
alert(car2.drivers)
五.动态原型方式:这种方式是极力推荐的方式,避免了前面几种方式所出现的问题,提供了更友好的编码风格
function Car(sColor, iDoors, iMpg){
this.color = sColor
this.doors = iDoors
this.mpg = iMpg
this.drivers = new Array("mike", "sue")
if(typeof Car.initialized == "undefined"){
Car.prototype.showColor = function (){
alert(this.color)
}
Car.initialized = true
}
}
var car1 = new Car("red", 4, 23)
var car2 = new Car("blue", 3, 25)
car1.drivers.push("matt")
alert(car1.drivers)
alert(car2.drivers)
六.混合工厂方式:和工厂方式有些相似,但采用new关键字实例化,具有和工厂方式相同的弊端,不推荐使用