函数javascript
js中的函数比较奇怪,不像C中,函数是最小的编译单元,也是实现一个功能的模块。js中,函数是Function类的一个实例,Function这个类有属性,有方法。这就意味着函数能够看成值参数传递。java
1. 函数的声明方式json
// 第一种方式 :定义式的声明 var show = new Function('varg1','varg2','alert(varg1 + varg2)') show(10,20) // 调用这个函数 // 第二种方式 函数是一个值。 var show1 = function (varg1, varg2) { alert(varg1 - varg2) }// 函数是引用类型,所以能够被变量show1引用 show1(20,10) // 第三种方式 function show3(var1,var2){ alert(var1 + var2) }
2.建立对象函数
// 第一种方法: 普通的对象属性的方式 var p1 = new Object() p1.name = 'zhangsan'//属性 p1.age = 34//属性 p1.say = function say(argument) {// 方法 alert(this.name+this.age) } // 第二种方式:json方式 p2 = { name:'meidong', age:40, say:function say(argument) { alert(this.name+this.age) } }
优势:建立方式灵活,简单容易。this
缺点:类模版无发被重复利用,使用工厂模式建立对象,类模版则可重用。spa
工厂模式建立对象:prototype
function Child(name,age) { var p1 = new Object()// 无发检测类型 p1.name = name p1.age = age p1.say = function say(argument) { alert(this.name+this.age) } return p1 } var c1 = new Child('haha',5); alert(typeof c1)// Object类型
优势:类可从用 。缺点:其它类的类型都是Object,类的类型无发检测。解决方法:使用构造函数可解决这个问题code
构造函数建立对象:对象
function Person(name,age) {// this.age = age this.name = name this.say = function say() { alert(this.name+this.age) } }// 能够重用了,能够监测类型。缺点是,方法占用内存空间 var p4 = new Person('maliu',45) alert(p4 instanceof Person)// ture var p3 = new Person('wangwu',20) alert(p3.say==p4.say)// faulse
优势:能够检测到是Person类型。缺点:类中的方法很是多的是,初始化一个类的实例,每一个方法都会占用内存空间。解决方法:把对象的方法,写成全局变量ip
function say() {// 全局变量 alert(this.name+','+this.age) } function Person(name,age) {// this.age = age this.name = name this.say = say }
优势:节省了对象建立是占用的内存。缺点:在window中能够随意调用。最好是封装在类中。这样的话就用到函数原型了
用函数原型封装类:
function Person() { }// 类中包含一个property属性,指向函数原型对象。并且全部对象实例共享原型对象的属性和方法。 var p1 = new Person()// 建立一个对象实例。 Person.prototype.name = 'leon' Person.prototype.age = 32 Person.prototype.friend = ['meidong','mark'] Person.prototype.constructor = Person Person.prototype.say = function say() { alert(this.name+','+this.age) } p1.say() //leon,32 p1.friend.push('mattt') var p2 = new Person() p2.say() //leon,32 alert(p1.say == p2.say)// ture alert(p1.friend)// ['meidong','mark','mattt'] alert(p2.friend)// ['meidong','mark','mattt']p2中也push到了mattt,这两个访问同一块内存,由于是引用类型去访问都函数的原型 say()// 报错,not find function
优势:得到了面向对象的封装特性 缺点:无发经过构造函数初始化属性,当属性引用类型,会形成变量重复。解决方法是 使用构造方法
function Child(name,age,friend) { this.name = name this.age = age this.friend = friend if (self.say != 'function') {//使用到会建立。 self.say = function () { alert(this.name+','+this.age) } } } var c1 = new Child('medong',20,['zhangsan','wangwu']) c1.friend.push('mattt') alert(c1.friend)// ['zhangsan','wangwu','mattt'] var c2 = new Child('jack',30,['mark','jess']) alert(c2.friend)// ['mark','jess']并无mattt