js函数的几种写法 闭包概要

JavaScript011

js函数的几种写法 闭包概要,第1张

最常见的:Js代码1functionfoo() {2alert('hi, js')3}4foo()用匿名函数:Js代码1varfoo =function() {2alert('hi, js')3}4foo()改装一下,给调用的foo()加个括号:Js代码1varfoo =function() {2alert('hi, js')3}4(foo)()干脆,连foo的定义也省掉------把foo赋值语句的等号右边的东东、直接替换掉刚才括起来的foo:Js代码1(function() {2alert('hi, js')3})()先看常用的函数:1functionsayHello(name) {2vartext = 'Hello ' +name3varsayAlert =function() { alert(text)}4sayAlert()5}6sayHello('Bob')闭包的例子一句话描述:闭包是函数的局部变量,在函数return之后,仍然有值, 或者闭包是stack-frame,在函数return的时候,它不会被释放。(就好像'stack-frame'是内存分配、而非处于堆栈!)下面的代码返回一个function的引用:1functionsayHello2(name) {2vartext = 'Hello ' + name//local variable3varsayAlert =function() { alert(text)}4returnsayAlert5}6varsay2 = sayHello2('Jane')7say2()//hello JaneC函数指针和JavaScript的函数引用有着本质的不同。在JavaScript,函数引用变量既是一个函数指针,又是一个隐藏的闭包指针。在C和其他多数语言,当函数return之后,stack-frame就被销毁了,所有的局部变量也就不能访问了。在JavaScript中,如果你在函数里声明了函数,在你调用的函数renturn之后,局部变量仍然可以访问。请注意上面的例子,我们调用了变量text,它是函数sayHello2的局部变量。Example 3这个例子表明局部变量不是拷贝传递,而是引用传递。在外层函数退出时,它把stack-frame保存在内存。1functionsay667() {2//Local variable that ends up within closure3varnum = 6664varsayAlert =function() { alert(num)}5num++6returnsayAlert7}8varsayNumba =say667()9sayNumba()//667,而不是66610alert(sayNumba.toString())Example 4三个函数对某个闭包使用同一个引用,因为它们均在setupSomeGlobals()里声明的。1vargAlertNumber = gIncreaseNumber = gSetNumber =null2functionsetupSomeGlobals() {3//Local variable that ends up within closure4varnum = 6665//Store some references to functions as global variables6gAlertNumber =function() { alert(num)}7gIncreaseNumber =function() { num++}8gSetNumber =function(x) { num =x}9}10setupSomeGlobals()11//任意、多次 运行下面的函数12gAlertNumber()13gIncreaseNumber()14gSetNumber(5)//把num重新设为 515gSetNumber(-8888)//把num重新设为 -8888重新运行setupSomeGlobals()就会重新产生一个新的闭包。在JavaScript中,当你在函数里又声明一个函数,外部函数每调用一次,内部函数将再被重新产生一次。Example 5当心下面例子的循环:闭包中的局部变量可能和你最初想的不一样。1functionbuildList(list) {2varresult =[]3for(vari = 0i <list.lengthi++) {4varitem = 'item' +list[i]5result.push(function() {alert(item + ' ' +list[i])} )6}7returnresult8}910functiontestList() {11varfnlist = buildList([1,2,3])12//using j only to help prevent confusion - could use i13for(varj = 0j <fnlist.lengthj++) {14fnlist[j]()15}16}1718testList()//输出3次:'item3 undefined'Example 6下面的例子表明,闭包包含了 在外部函数退出之前、定义的任何局部变量。注意,变量alice实际上在匿名函数之后声明的。匿名函数先被声明:当函数被调用时,它可以访问alice,因为alice在闭包里。1functionsayAlice() {2varsayAlert =function() { alert(alice)}3//Local variable that ends up within closure4varalice = 'Hello Alice'5returnsayAlert6}7sayAlice()()//Hello Alice8alert(alice)//错误:alice不是全局变量,它在函数体内var了Example 7下面的例子表明,每次调用会产生各自的闭包。1functionnewClosure(someNum, someRef) {2//Local variables that end up within closure3varnum =someNum4varanArray = [1,2,3]5varref =someRef6returnfunction(x) {7num +=x8anArray.push(num)9alert('num: ' + num +10'\nanArray ' + anArray.toString() +11'\nref.someVar ' +ref.someVar)12}13}14closure1 = newClosure(40, {someVar : 'closure 1'})15closure1(5)1617closure2 = newClosure(1000, {someVar : 'closure 2'})18closure2(-10)小结读一些说明要比理解上面的例子难得多。我对于闭包的说明以及stack-frame等等在技术上可能不正确 --- 但是它们的确有助于理解

由于js类的定义方法和函数的定义方法一样,

所以定义类的同时就定义了构造方法。

function Person(name,sex){ // 类,同时定义构造方法

this.eat=function(){ // 类中的方法

alert("eating")

}

this.name = name// 类中的属性

this.sex = sex

}

这几种方法每一个都有不一样的作用。

1.myfun:function(){} 这个是必须写在对象内部的,这是一个对象的方法,如

var a = {

   myfun:function(){} 

}

写在外面会报错。

2.任何时候都不要这样写myfun = function(){},这样写就变成了全局对象window的一个属性,要记得加上var ,第四种方式是对的,如下:

var myfun = function(){}

这是一种声明函数的方式,左边是一个变量,右边是一个函数的表达式,意思就是把一个匿名的函数表达式复制给了变量myfun,只是声明了一个变量指向了一个函数对象。这个和第三种方法function myfun(){}声明的方法差别不大,但还是有差别的。

这就要涉及到javascript解析的部分了,简单来说,js在解析的过程中,会先把函数和变量提前解析。

function myfun(){}这种声明方法会把函数整个语句显示的提前到了脚本或者函数前(当前作用域),函数名和函数均会被提前(会在执行上下文代码前声明)。

而var myfun = function(){}这种声明方法,只是提前了一个变量,并没有提前函数体。

3.最后一种并不是声明的函数,只是在myfun函数上的原始对象上加了一个myfunPro方法,构造函数中用到的。给你个例子:

var myfun = function(){

  this.a = "a"

  }

  myfun.prototype.myfunPro = function (){

  alert("0")

  }

  var test = new myfun()

  console.log(test)

运行结果如下图:

这时候如果你在最底部加上一段代码,如下:

var myfun = function(){

  this.a = "a"

  }

  myfun.prototype.myfunPro = function (){

  alert("0")

  }

  var test = new myfun()

  console.log(test)

  test.myfunPro()

这时候就会弹出一个对话框 0了 ,你可以试试