js函数有哪些特点

JavaScript020

js函数有哪些特点,第1张

1,如果没有return语句,默认返回是uedefined2,函数内部包含一个默认的arguments参数数组,它返回函数所接收的所有参数3,如果在函数中声明一个变量没有使用var,这个变量将默认为全局变量4,函数域始终高于全局域5,函数也是数据6,typeof 函数名 返回 function7,闭包7-1,作用域链JavaScript中不存在块作用域,存在函数作用域,在函数内,能够访问全局和函数域的变量,在函数外,只能访问全局域的变量7-2,词法作用域 每个函数在定义时(而非执行时)都会创建一个属于自己的环境(作用域),function f1(){var a=1f2()} function f2() {return a} f1()=>a is notdefined当f2定义时,变量a是不可见的7-3,利用闭包突破作用域链

只写上函数体实际上不是执行代码,而是声明代码,意思说,我现在有一个函数名字叫做foo,而随后在函数体外写函数名加括号表示真正“执行”这个函数,即通知浏览器调用这个函数体内的详细步骤。

Function.prototype.method = function (name, func) {//在Function的原型上增加一个函数叫做“method”。该方法会在“类”的原型上增加指定函数名的函数。

    if (!this.prototype[name]) {

        this.prototype[name] = func

    }

}    

Object.method('superior', function (name) {//增加一个超级方法。该方法保存它从原型上继承来方法。用来模拟面向对象中的super关键字。

    var that = this,

        method = that[name]

    return function (  ) {

        return method.apply(that, arguments)

    }

})

var mammal = function (spec) {//定义一个哺乳动物类型。

    var that = {}

    that.get_name = function (  ) {//获取动物名字。

        return spec.name

    }

    that.says = function (  ) {//动物打招呼的方法。

        return spec.saying || ''

    }

    return that

}

//var myMammal = mammal({name: 'Herb'})//创建一个哺乳动物的实例。

var cat = function (spec) {//定义一个“猫”的类型。

    spec.saying = spec.saying || 'meow'//为这个类型指定一个“叫声”,这里是“喵”

    var that = mammal(spec)//创建一个哺乳动物实例。

    that.purr = function (n) {//为这个哺乳动物创建一个猫的咕噜咕噜声音的方法“purr”

        var i, s = ''

        for (i = 0 i < n i += 1) {

            if (s) {

                s += '-'

            }

            s += 'r'

        }

        return s

    }

    that.get_name = function (  ) {//获取“猫”的名字。猫的叫声(meow) + 猫的名字 + 猫的叫声(meow)

        return that.says(  ) + ' ' + spec.name +

                ' ' + that.says(  )

}

    return that

}

var myCat = cat({name: 'Henrietta'})//创建一只猫的实例。名字叫Henrietta

var coolcat = function (spec) {//创建一个“酷猫”的类型

    var that = cat(spec),//创建一只普通猫。

        super_get_name = that.superior('get_name')//保存普通猫的“获取名字”的方法。

    that.get_name = function (n) {//酷猫有自己的“获取名字”的方法,“like” + 普通猫的“获取名字方法” + “baby”

        return 'like ' + super_get_name(  ) + ' baby'

    }

    return that

}

var myCoolCat = coolcat({name: 'Bix'})//创建一只酷猫。

var name = myCoolCat.get_name(  )//酷猫的名字是like meow Bix meow baby

//        'like meow Bix meow baby'

上面采用prototype(原型扩展)的方式来实现“类”的继承,如,酷猫 >继承 >猫 >继承 >哺乳动物。

而下面采用了另外一种思路:使用工厂模式来创建对象,不是通过复用原型。而是拆分零部件。每个部件都是可拆卸,可组装的方式,来达到另一种代码复用的效果。

function createCar(numberOfDoors){//造车厂,指定门的数量,并制造一辆汽车。

  var numberOfWheels = 4//轮子的数量是4.

  function describe(){//描述一下车辆。

    return "I have " + numberOfWheels + " wheels and " + numberOfDoors + " doors."

  }

  return {//返回制造完成的汽车。

    describe: describe

  }

}

function createOdometer(){//加工车载里程计。

  var mileage = 0

  function increment(numberOfMiles){ mileage += numberOfMiles}//里程计跑表的方法

  function report(){ return mileage }//报告当前的里程数

  return {//返回制造完成的里程计

    increment: increment,

    report: report

  }

}

function createCarWithOdometer(numberOfDoors){//制造带有里程计的汽车

  var odometer = createOdometer()//制造一个里程计

  var car = createCar(numberOfDoors)//制造一辆车

  car.drive = function(numberOfMiles){//将里程计安装到汽车上,当汽车行驶的过程中,调用里程计的跑表方法。

    odometer.increment(numberOfMiles)

  }

  car.mileage = function(){//报告汽车的里程,通过已安装的里程计的报告方法,获取里程。

    return "car has driven " + odometer.report() + " miles"

  }

  return car//返回制造并组装完毕的汽车。

}

var twoFn=createCarWithOdometer(100)//创造一辆带有100个门的汽车(当然不可能。。Σ( ° △ °|||)︴)

console.log(twoFn)

上述两种方式,体现了javascript的精妙之处。

在面向对象语言中:

采用了类继承的方式,实现代码复用。

在javascript中,并没有真正的类。而是用“function”来代表一种类型,

比如:

function Person(){}

我们可以认为,Person就是所谓的javascript中的“类”的概念。我们可以这样

var p = new Person()

alert(p instanceof Person)//结果是true,因为p就是Person类型的一个实例。

alert(p instanceof Object)//结果也是true,因为所有实例终归都是Object。

而每个类型是如果扩展自己的新方法的呢?就是通过类型的prototype这个属性。

只有function才有prototype属性。

比如:

function Person(){}

Person.prototype.say = function(){alert('hello')}//人这种类型有打招呼的方法

var p1 = new Person()

var p2 = new Person()

p1.say()//hello

p2.say()//hello

这样,所有实例就都可以用打招呼的方法了。

当我们创建一个新的类型“男人”。想要继承Person的话。就像下面这样:

function Man(){}

var proto = Man.prototype = new Person()//男人也是人啊,男人的原型就是以一个普通人为标准来参考的,所以我们创建一个人类,赋值给男人,让男人来学习,参考人的特性。

proto.fight = function(){//男人比起人来,脾气大,因此有个打架的方法。

    alert('I\'ll kick your ass!!')

}

var m = new Man()

m.say()//hello

m.fight()//I'll kick your ass.这就是传说中的一句话说不上来就开打。。。

原型继承的核心就是这样的。

而另外一种思路就是工厂模式。

小汽车厂

轮子厂

里程计厂

卡车厂

小汽车厂需要轮子和里程计,分别向“轮子厂”和“里程计厂”要来了两个现成的产品,直接安装好,就完成了一辆小汽车。

卡车长也是一样的。所以这种方式也是一种很好的代码结构。