zoukankan      html  css  js  c++  java
  • 第4章-函数(1)

    函数对象 Functions

    对象是“名/值”对的集合并拥有一个连到原型对象的隐藏链接。对象字面量产生的对象链接到Object.prototype。函数对象连接到Function.prototype(该原型对象本身链接到Object.prototype)。每个函数在创建时会附加隐藏属性:函数的上下文和实现函数行为的代码。

    每个函数对象在创建时也有一个prototype属性,它的值是一个拥有constructor属性且值即为该函数的对象。

     

    函数字面量 Function Literal

    函数对象通过函数字面量来创建

    1         var add = function (a,b){
    2             return a+b;
    3         };

    一个内部函数除了可以访问自己的参数和变量,同时它也能自由访问把它嵌套在其中的父函数的参数和变量。通过函数字面量创建的函数对象包含一个连到外部上下文的链接。这被称为闭包。

     

    调用 Invocation

    调用一个函数会暂停当前函数的执行,传递控制权和参数给新函数。除了声明定义的形式参数,每个函数还接受两个附加的参数:this和arguments。参数this在面向对象编程中非常重要,它的值取决于调用的模式。在JavaScript中一共有4种调用模式:方法调用模式、函数调用模式、构造器调用模式和apply调用模式。这些模式在如何初始化关键参数this上存在差异

     

    方法调用模式 The Method Invocation Pattern

    当一个函数被保存为一个对象的属性时,我们称它为一个方法。当一个方法调用时,this被绑定到该对象。

     1         var myObject = {
     2             value: 0,
     3             increment: function (inc){
     4                 this.value += typeof inc === 'number' ? inc : 1;
     5             }
     6         };
     7 
     8         myObject.increment();
     9         console.log(myObject.value); //1
    10 
    11         myObject.increment(2);
    12         console.log(myObject.value); //3

    方法可以使用this访问自己所属的对象,所以它能从对象中取值或对对象进行修改。通过this可取的它们所属对象的上下文的方法称为公共方法

     

    函数调用模式 The Function Invocation Pattern

    当一个函数并非一个对象的属性时,那么它就是被当做一个函数来调用的:

    1     var sum = add(3,4); //sum的值为7

    以此模式调用函数时,this被绑定到全局对象。这是语言设计上的一个错误,应当一个内部函数被调用时,this应该被绑定到外部函数的this变量。比如:

     1         var value = 2;
     2 
     3         var test = {
     4             value:100,
     5             increment:function(){
     6                 this.value = this.value + 100;
     7                 var output = function(){
     8                     console.log(this.value);
     9                 };
    10                 output();
    11             }
    12         };
    13 
    14         test.increment(); //2

    可以看到最后输出的结果是 2 ,this.value指向的是全局变量中的value。有一个很容易的解决方案就是在对象中将this赋值给另外一个变量

     1         var value = 2;
     2 
     3         var test = {
     4             value:100,
     5             increment:function(){
     6                 var that = this;
     7                 that.value = that.value + 100;
     8                 var output = function(){
     9                     console.log(that.value);
    10                 };
    11                 output();
    12             }
    13         };
    14 
    15         test.increment(); //200

     

    构造器调用模式 The Constructor Invocation Pattern

    如果在一个函数前面带上new来调用,那么背地里将会创建一个连接到该函数的prototype成员的新对象,同时this会被绑定到那个新对象上。

     1         //创建一个名为Quo的构造器函数,他构造一个带有status属性的对象
     2         var Quo = function (string){
     3             this.status = string;
     4         };
     5 
     6         Quo.prototype.get_status = function(){
     7             return this.status;
     8         };
     9 
    10         var myQuo = new Quo("confused");
    11         console.log(myQuo.get_status()); //confused

    一个函数,如果创建的目的就是希望结合new前缀来使用,那它被称为构造器函数,按照约定,他们保存在以大写格式命名的变量里。

     

    Apply 调用模式 The Apply Invocation Pattern

    apply方法让我们构建一个参数数组传递给调用函数。它接受两个参数,第1个是要绑定给this的值,第2个就是一个参数数组。

    1         var array = [3,4];
    2         //apply第一个参数传递为null,并不是说将add函数的运行上下文环境设置为null,而是设置为全局对象window
    3         var sum = add.apply(null,array); //sum的值为7
    4 
    5         var statusObject = {
    6             status: 'A-OK'
    7         };
    8         //statusObject并没有继承自Quo.prototype,但我们可以在statusObject上调用get_status方法,尽管statusObject没有这个方法
    9         var status = Quo.prototype.get_status.apply(statusObject);//status的值为'A-OK'

     

    参数 Arguments

    函数可以通过此参数访问所有它被调用时传递给它的参数列表,包括哪些没有分配给函数声明时定义的形式参数的多余参数

    1         var sum = function(){
    2             var i,sum = 0;
    3             for(i=0;i<arguments.length;i++){
    4                 sum += arguments[i];
    5             }
    6             return sum;
    7         }
    8 
    9         console.log(sum(10,20,56,48,2,36,98)); //270

     

    返回 Return

    一个函数总是会返回一个值,如果没有指定返回值,则返回underfined

    如果函数调用时在前面加上了new前缀,且返回值不是一个对象,则返回this(该新对象)

     

    异常 Exceptions

    异常是干扰程序正常流程的不寻常,当发现这样的事故,应该抛出一个异常:

     1         var add = function(a,b){
     2             if(typeof a !== 'number' || typeof b !== 'number'){
     3                 throw{
     4                     name: 'The Most Serious Error',
     5                     message: 'you are too handsome',
     6                     from: 'Qq'
     7                 };
     8             }
     9             return a + b;
    10         }
    11 
    12         //throw语句中断函数的执行,它应该抛出一个exception对象,该对象包含一个用来识别异常类型的name属性和一个描述性的message属性。你也可以添加其他的属性。
    13         //该exception对象被传递到一个try语句的catch从句:
    14 
    15         var try_it = function(){
    16             try{
    17                 add("seven");
    18             }catch(e){
    19                 console.log(e.name + ": " + e.message + "  " + e.from);
    20             }
    21         }
    22 
    23         try_it(); //The Most Serious Error: you are too handsome  Qq

    如果在try代码块内抛出了一个异常,控制权就会跳转到它的catch从句。一个try语句只会有一个捕获所有异常的catch代码块。如果你的处理手段取决于异常的类型,那么异常处理器必须检查异常对象的name属性来确定异常的类型

     

    扩充类型的功能 Augmenting Types

    JavaScript允许给语言的基本类型扩充功能。举例来说我们可以给Function.prototype增加方法来使得该方法对所有的函数可用:

     1         Function.prototype.method = function(name,func){
     2             this.prototype[name] = func;
     3             return this;
     4         };
     5 
     6         //给Number.prototype增加一个integer方法来改善它,他会根据数字的正负来判断使用Math.ceiling还是Math.floor。
     7 
     8         Number.method('integer',function(){
     9             return Math[this < 0 ?'ceil' : 'floor'](this);
    10         });
    11 
    12         console.log((10/3).integer()); //3

    基本类型的原型式公用的,所以在类库混用时务必小心。一个保险的做法就是只在确定没有该方法时在添加它

    1         Function.prototype.method = function(name,func){
    2             if(!this.prototype[name]){
    3                 this.prototype[name] = func;
    4             }
    5             return this;
    6         };
    不要在该奋斗的年纪而选择了安逸
  • 相关阅读:
    SQL2005 SQL2008 远程连接配置方法
    Subvision 安装 部署 TortoiseSVN
    在wpf或winform关闭子窗口或对子窗口进行某个操作后刷新父窗口
    C# 中的委托和事件
    长数字隔三位用逗号","隔开,保留两位小数,指定长度,不足补空格
    C# 柱状图, 折线图, 扇形图
    如何在Visual Studio 2010旗舰版本下安装Window Phone 7 简体中文开发环境
    vs2010发布、打包安装程序(超全超详细)
    java 环境搭建
    SQL2008 转 2000(高版本转换到低版本)
  • 原文地址:https://www.cnblogs.com/qqandfqr/p/5954533.html
Copyright © 2011-2022 走看看