一、函数的声明方式

1、普通的函数声明

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

2、使用变量初始化函数

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

3、使用Function构造函数

var box=new Function("num1","num2","return num1+num2");
alert(box(1,2));

第三种不推荐,因为这种语法导致解析两次代码(第一次解析常规ECMAScript代码,第二次解析传入构造函数中的字符串)
,从而影响性能,但我们可以通过这种语法来理解,函数是对象,函数名是指针的概念

二、作为值的函数,函数可以传递函数

1、函数的返回值可以来传递

function box(sum,num){
return sum+num;
}
function sum(num){
return num+10;
}
var result=box(sum(10),10); //这里传递的是函数的返回值,和普通变量没区别
alert(result);

2、把函数本身作为参数来传递,而不是作为结果

function box(sum,num){
return sum(num);
}
function sum(num){
return num+10;
}
var result=box(sum,10) //这里sum是函数,当做参数传递到另外一个函数里,而不是返回值
alert(result)

三、函数内部属性

1、arguments类数组对象,包含了传入函数中所有参数,这个对象还有一个callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数

function box(num){
if(num<=1){
return 1;
}else{
return num*box(num-1); //3*2*1
}
}
alert(box(3));

以上是一个阶乘或者是递归,box调用了自己,如果很多自我调用修改也许会麻烦,所以用到arguments.callee来调用自己

function box(num){
if(num<=1){
return 1;
}else{
return num*arguments.callee(num-1); //arguments.callee 调用自身,实现递归
}
}
alert(box(3));

2、this

四、函数的属性和方法

1、length   函数希望接收参数个数

function box(a,b){
return a+b;
}
alert(box.length) //2

2、prototype  原型,下面有两个方法 apply()和call(),每个函数都包含这两个非继承而来的方法,这两个方法的用途都在特定的作用域中调用函数,实际上等于设置函数体内this对象的值

function box(a,b){
return a+b;
}
function sum(a,b){
return box.apply(this,[a,b]); //this表示window作用域,[]表示传递的参数
}
function sum1(a,b){
return box.apply(this,arguments); //这个可以当数组传递
}
alert(box(10,10));alert(sum(10,10));
alert(sum1(10,10));

call()和apply()方法相同,他们的区别在于接收参数方式不同。对于call()方法,第一个参数也是作用域,没有变化,变化只是其余的参数都是直接传递给函数的

function box(a,b){
return a+b;
}
function sum(a,b){
return box.call(this,a,b); //this表示window作用域,[]表示传递的参数
}
alert(box(10,10));
alert(sum(10,10));

以上是对象冒充,其实call()和apply()最大的作用是修改作用域

var color="hongse";
var box={
color:"lanse"
}
function sayColor(){
alert(this.color);
}
sayColor.call(window);
sayColor.call(this); //this就是window
sayColor.call(box);

----------------------------------------------进阶----------------------------------------------

1、当函数作为对象的方法时,this指向该对象

2、作为普通函数调用时(当函数不作为对象属性调用时,也就是普通函数方式,此时的this总是指向全局对象,在JavaScript中,这个全局对象是Window对象

例子1:

var myObject={
name:"sven",
getName:function(){
return this.name;
}
}
console.log(myObject.getName()) //sven
var myObject1=myObject.getName; window.name="lee"; console.log(myObject1()) //lee

例子2:

var div=document.getElementById('div1');
div1.onclick=function(){
console.log(this); //这里的this是dom节点
function callback(){
console.log(this); //这里的this是window,因为是作为普通函数调用的
}
callback();
}
-------修改方法,callback.call(this)

3、使用new调用构造器时,如果构造器显示返回一个object类型的对象,那么这次结果最终会返回这个对象,而不是之前期待的this

例1

var myObject=function(){
this.name="sven";
return {
name : "anne" //返回object类型
}
}
var obj=new myObject();
console.log(obj.name) //输出 anne

4、Function.prototype.call 或 Function.prototype.apply 调用

跟普通函数相比,用Function.prototype.call 或 Function.prototype.apply可以动态的改变传入函数的this

例1

var obj1={
name:"sven",
getName:function(){
return this.name;
}
}
var obj2={
name:"annr"
}
console.log(obj1.getName()); //输出 sven
console.log(obj1.getName.call(obj2)); //输出 anne
-------------call是function方法-----------

5、call和apply

apply接收两个参数,第一个参数指定了函数体内this对象的指向,第二个是个集合(可以是数组,也可以是类数组)

var func=function(a,b,c){
console.log([a,b,c]);
}
func.apply(null,[1,2,3]) //[1,2,3]

其实和之前学的是一样的,调用函数的时候,都省略了call或apply,比如调用 a(),其实是a.apply()的缩写,只不过,第一个参数是null,函数体内的this会指向默认的宿主对象,在浏览器中则是window

var func=function(a,b,c){
console.log(this===window);
}
func.apply(null,[1,2,3])

***借用其他对象的方法

有时候我们使用call或者apply的目的不在于指定this指向,而是另有用途,比如借用其他对象的方法,传入null代替某个具体的对象

Math.max.apply(null,[1,2,5])     //

借用Array.prototype对象上的方法,往arguments中添加一个新的元素,通常会借用Array.prototye.push方法

(function(){
Array.prototype.push.call(arguments,3)
console.log(arguments)
})(1,2) //[1,2,3] 把任意对象传入Array.prototype.push
var a={};
Array.prototype.push.call(a,"frist");
a[0]; //frish
a.length; //

想把arguments转成真正的数组的时候,可以借用Array.prototype.slice方法,想截去arguments列表的头一个元素的时候,可以借用Array.prototype.shift方法

(function(){
Array.prototype.slice.call(arguments)
console.log(arguments)
})(1,2) //[1,2] (function(){
Array.prototype.shift.call(arguments)
console.log(arguments)
})(1,2) //[2]

function 类型的更多相关文章

  1. 引用类型-Function类型

    Function类型 定义函数的三种方式: 1.函数声明 function sum(num1,num2){ return num1 +num2; } 2.函数表达式 var sum = functio ...

  2. 【笔记】js Function类型 内部方法callee

    运用function实现阶乘 以往的做法是如下的 function factorial(num){ if(num <= 1){ return 1; }else{ return num * fac ...

  3. Function类型

    1.每个函数都是Function类型的,和其他引用类型一样都具有属性和方法.函数也是对象,因此函数实际上是一个指向函数对象的指针. 函数声明语法定义: 方法1: function sum(num1,n ...

  4. JavaScript笔记——引用类型之Object类型和Function类型

    <JavaScript高级程序设计>中介绍的几种JavaScript的引用类型,本文只记了Object跟Function类型 Object类型 创建对象 var person = new ...

  5. String类型,Function类型

    1.String类型:  1)创建String对象:    var str=new String(s);    String(s);    参数:参数 s 是要存储在 String 对象中的值或转换成 ...

  6. JavaScript高级 Function类型

    ·    Function类型 (属于引用类型) 1.JS中,有的函数均是对象,这个一个非常有特点的地方.它既然是对象,那么它的构造函数是谁呢?就是Function.(例如:function Pers ...

  7. 浅析JavaScript之Function类型

    JavaScript中的函数实际上是对象,每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法.由于函数是对象,因此函数名实际上只是指向函数对象的指针,保存函数在堆内存中的地 ...

  8. 笔记——Function类型 及其 call、apply方法

    每个函数都是Function类型的实例.函数有三种定义方式和两个内部属性arguments和this. 同时函数也是对象,也有属性和方法.本篇主要其call()和apply()方法 属性 length ...

  9. 引用类型之Function类型

    Function类型 ECMAScript中最有意思的就是函数了,有意思的根源,在于函数实际上是对象.每个函数都是Function的实例,具有属性和方法.而重要的一点是,函数名,不过是指向函数的指针, ...

  10. 第十一章 Function类型

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

随机推荐

  1. UVA 11489 - Integer Game(找规律)

    题目链接 #include <cstdio> #include <cstring> #include <string> #include <cmath> ...

  2. LINQ to Entities 事务简单例子

    默认LINQ to Entities会使用隐式事务,即:对于每一个savechanges都分开在单独的事务之中. 也可以显式地指定事务: using (var db = new TestEntitie ...

  3. 你用java的swing可以做出这么炫的mp3播放器吗?

    这个mp3播放器是基于java的swing编写的,我认为界面还是可以拿出来和大家看一看评一评. 先说说创作的初衷,由于前段时间工作不是很忙,与其闲着,还不如找一些东西来给自己捣腾捣腾,在 之前写的 j ...

  4. 1071. Speech Patterns (25)

    People often have a preference among synonyms of the same word. For example, some may prefer "t ...

  5. awesome-scala

    https://github.com/lauris/awesome-scala Awesome Scala  A community driven list of useful Scala libra ...

  6. 关于mysql(或MariaDB)中的用户账号格式

    之前在修改数据库本地root用户密码时,发现我远程连接的root用户的密码并没有改变,之后查了一下,发现原来这两个root不是同一个用户(汗..) 于是联想到之前配置数据库每次给用户赋予远程连接权限时 ...

  7. 使用RMAN备份数据库

    1.1使用控制文件备份全库 1.1.1配置备份路径 1.1.2 RMAN备份全库 1.2使用catalog数据库备份全库 1.2.1配置到远程数据库的TNS 1.2.2创建表空间及设置用户 1.2.3 ...

  8. ie上 CSS3114: @font-face 未能完成 OpenType 嵌入权限检查。(包括图标无法显示)

    转自:http://blog.csdn.net/shore_w/article/details/8976188 @font-face是CSS3中的一个模块, 它主要是把自己定义的Web字体嵌入到网页中 ...

  9. js sort() 排序的问题

    默认并非按照大小排序,而是根据Assic来排序的,但接受一个排序函数.所以正确的使用姿势应该是这样的: var arr = [0,1,5,10,15]; function sequence(a,b){ ...

  10. 使用EXECUTE IMMEDIATE来生成含有绑定变量的SQL

    一个SQL,通过SPM固定它的执行计划,可以通过DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE实现.也可以通地此功能在不修改原SQL的情况下对其加HINT来固定执行计划.D ...