函數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