在ECMAScript中,Function(函数)类型实际上是对象。每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象指针

1、三种函数声明的方式

1》第一种:普通方式声明函数

 function box (num1,num2){
return num1+num2;
}

2》第二种:使用变量初始化的方式:

 var box =function(num1,num2){
return num1+num2;
};

 3》第三种:使用Function构造函数的方式

 var box =new Function("num1",'num2','return num1+num2');

总结:第三种方式不推荐使用:因为要解析两次代码:第一次:解析常规的ECMAScript代码,第二次是解析传入构造函数中的字符串;所以影响性能。但是我们能从这种语法理解“函数是对象,函数名是指针”这个概念

2、作为值的函数

ECMAScript中的函数本身就是变量,所以函数也可以作为值来使用。也就是说,不仅可以传递参数一样把一个函数传递进另一个函数,而且也可以将一个函数作为另一个函数的结果返回。类似于 c# 中的 委托,令方法 像参数一样传递到另一个方法中。

 function box(sum,num){//将函数 以参数的 形式 传递进 另一个函数
return sum(num); //将函数作为返回值 进行返回
} function sum(num){
return num+10;
}
alert(box(sum,10));//

3、函数内部的属性

在函数内部,有两个特殊的对象:arguments和this。arguments 是一个 类数组对象,包含着传入函数中的所有参数,主要用途是保存函数参数,但这个对象还有一个名叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数

arguments属性的使用:

 function box(){
alert(arguments.length);
for(var i=0;i<arguments.length;i++){
alert(arguments[i]); //取到每一个传进来的参数
}
} box(1,2,3,4);

callee属性(是arguments的属性)

 //使用arguments.callee代替 自己
function sum(num){
if(num<=1){
return 1;
}
else{
return num * arguments.callee(num-1);
}
}
alert(sum(4));//

 this对象:

和c#中的this大致相似。this对象引用的是函数以执行操作的对象,或者说函数调用语句所处的那个作用域。

PS:当在全局作用域中调用函数时,this对象引用的就是window。

 var color='红色';
alert(window.color);//红色 只要是全局作用域内的对象 就是 window下
alert(this.color)//红色 this位于全局作用域下,this引用的就是window对象
alert(color);//红色 可以省略 window直接输出 window.color='蓝色'; //等价于:var color='蓝色';
alert(this.color);//蓝色
alert(color);//蓝色

this在全局范围内

this对象的经典的例子:

 var box={
color:'红色',
SayColor:function(){
alert(this.color); //this对象 指向的此作用域 范围内的 对象的引用(就是box的引用)
}
};
box.SayColor(); window.color='红色';
function SayColor(){
alert(this.color);//因为此方法位于 window下面,所以 方法内的this引用指向 window
} SayColor();//红色 var box={
color:'蓝色的'
};
box.SayColor=window.SayColor; //赋值之后,SayColor中的this对象 指向 当前的 作用域 也就是 box对象
box.SayColor();//蓝色的

this经典例子

4、匿名属性和方法

ECMAScript中的函数式对象,因此函数也有属性和方法。每个函数都含有两个属性:length和prototype。其中,length表示函数希望接收的命名参数的个数

PS:prototype属性:它是保存所有实例方法的真正所在,也就是原型。这个属性。我们将在面向对象一章详细介绍。而prototype下有两个方法:apply()和call(),每个函数都包含这两个 非继承 而来的方法。这两个方法的用途都在特定的作用域中调用函数,实际上等于设置函数体内this对象的值

length属性:

 function sum(num1,num2){
return num1+num2;
}
alert(sum.length);

apply()方法:

 function sum(num1,num2){
return num1+num2;
} function num(num1,num2){
//第一个参数:此方法要执行的作用域(就是这个方法执行的作用域),第二个参数是 要传递到sum函数中的参数
return sum.apply(this,[num1,num2]); //参数数组[num1,num2]可以使用 arguments替换
} alert(num(10,10));

apply()方法

call()方法:

call()方法执行的效果和apply是一样的,不同之处是:他们之间传递参数的方式的不同

 function box(num1,num2){
return sum.call(this,num1,num2);//从第二参数开始想函数内传递参数,而不是传递一个参数数组
//其实可以直接 调用函数,上面做法只是演示一下 apply 和call的用法
} alert(box(1,2));

call()方法

call()和apply()方法的真正的用武之地不是上面(因为上面实现没意义),而是:改变方法的作用域冒充方法的调用者进行调用方法,解决的是 对象之间的 “耦合”,降低了 耦合度

 var color='红色';

 function SayColor(){
alert(this.color);
}
SayColor();//红色 var box={
color:'蓝色'
}; SayColor.call(box);//蓝色 (改变了 方法的 作用域,但是没有 使用 box.SayColor=SayColor;(耦合度太高了),降低了耦合度) 在运行call(box)方法的时候,SayColor()的运行环境已经变成了box对象里了。
SayColor.call(this);//红色
SayColor.call(window);//红色 box.Say();

call()和apply()方法的最大好处:扩充作用域,并且 对象和方法之间不用发生任何的 耦合 关系

js之Function原型的更多相关文章

  1. JS高级——Function原型链

    基本概念 1.函数可以通过Function new出来,那么Function可以被称作构造函数,被new出来的函数可以被称为一个对象 2.Function既然是构造函数,那么肯定也有原型,它的原型是一 ...

  2. JS中的原型继承机制

    转载 http://blog.csdn.net/niuyongjie/article/details/4810835 在学习JS的面向对象过程中,一直对constructor与prototype感到很 ...

  3. js中的原型、继承的一些想法

    最近看到一个别人写的js类库,突然对js中的原型及继承产生了一些想法,之前也看过其中的一些内容,但是总不是很清晰,这几天利用空闲时间,对这块理解了一下,感觉还是有不通之处,思路上没那么条理,仅作为分享 ...

  4. 关于Function原型对象和Object原型对象的一些疑惑

    网上有一道美团外卖的面试题是这样的: Function.prototype.a = 'a'; Object.prototype.b = 'b'; function Person(){}; var p ...

  5. 基于原生JS封装数组原型上的sort方法

    基于原生JS封装数组原型上的sort方法 最近学习了数组的原型上内置方法的封装,加强了用原生JS封装方法的能力,也进一步理解数组方法封装的过程,实现的功能.虽然没有深入底层,了解源码.以下解法都是基于 ...

  6. 谈谈JS中的原型

    不知道大家对JS中的原型理解的怎么样,我想如果大家对JS中的原型对象以及prototype属性十分熟悉的话对后面原型链以及继承的理解会十分的容易,这里想和大家分享自己对其的理解,请先看下面这段代码O( ...

  7. js中原型和原型链

    1.原型: 在JavaScript 中,对象被表现为prototype . 原型其实一直存在于我们接触过的任何一个对象. 2. Tip:在函数对象中也存在__proto__属性,但是查看函数对象的原型 ...

  8. JS面向对象,原型,继承

    ECMAScript有两种开发模式:1.函数式(过程化),2.面向对象(OOP).面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.但是,ECMAScript ...

  9. JS对象与原型

    一. JS的对象 1.1 创建对象的几种方式 1.1.1 通过字面量创建对象 在js中,一对{} 其实就是一个对象 var person = { name: "tom", age: ...

随机推荐

  1. hdu2097

    #include <stdio.h> int sum1(int n,int sign){ ; while(n){ sum+=n%sign; n/=sign; } return sum; } ...

  2. .NET中使用log4net

    一,加载log4net引用 下载log4net.dll,我们这里使用的是.NET2.0 下载地址:http://files.cnblogs.com/gosky/log4net-1.2.13-bin-n ...

  3. javaSE第二十天

    第二十天    254 1:递归(理解)    254 (1)方法定义中调用方法本身的现象    254 (2)递归的注意事项    255 (3)递归的案例:    255 A:递归求阶乘    2 ...

  4. Openvz特点和分析

    OpenVZ是开源软件,是基于Linux平台的操作系统级服务器虚拟化解决方案.OpenVZ采用SWsoft的Virutozzo虚拟化服务器软件产品的内核,Virutozzo是SWsoft公司提供的商业 ...

  5. [Redis] RDB & AOF

    http://my.oschina.net/davehe/blog/174662 rdb - 存在dump.rdb 的二进制文件中 dump 整个db, 数据多的时候,不合适频繁保存,保存的时间间隔应 ...

  6. 一、MongoDB的下载、安装与部署

    1.什么是MongoDB? 它是介于关系型数据库和非关系型数据库之间的一种NoSQL数据库,用C++编写,是一款集敏捷性.可伸缩性.扩展性于一身的高性能的面向文档的通用数据库. 2.为什么要用Mong ...

  7. ViewGroup 和 View 事件传递及处理小谈

    前言 在自定义组件的时候少不了会去处理一些事件相关的东西,关于事件这块网上有很多文章,有说的对的也有说的不对的,我在理解的时候也有过一段时间的迷惑,现在把自己理解的东西写下来,给有相同疑问的朋友提供些 ...

  8. Android之Selector、Shape介绍

    ------------整理自网络---------------------- <?xml version=”1.0″ encoding=”utf-8″?> <shape xmlns ...

  9. 【推介】TMS的控件之“TMS Unicode Component Pack”和“TMS Advanced Toolbars & Menus”

    TMS Unicode Component Pack是一款支持多语言的界面控件包,提供超过60种控件来为你的Delphi和C++Builder应用程序添加Unicode支持. 介绍: TMS Unic ...

  10. delphi 基础之一 数据类型和基本语法

    1. 数据类型 特定类型 日期和时间 Delphi 也用实型数表示日期和时间数据.但为了更准确起见,Delphi 特别定义了TDateTime 数据类型,这是一个浮点类型,因为这个类型必须足够宽,使变 ...