一、函数的声明方式

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. 【BZOJ】2172: Mario填格子

    题意 \(3 * 3\)的网格,给出左上角的数字\(m\)和右下角的数字\(m\),如果当前格子有数字\(x\),格子左边有个数字\(y\),格子上面有个数字\(z\),则\(y|x, z|x\).格 ...

  2. 【POJ】3974 Palindrome

    http://poj.org/problem?id=3974 题意:求s的最长回文串.(|s|<=1000000) #include <cstdio> #include <cs ...

  3. BZOJ4551: [Tjoi2016&Heoi2016]树

    Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标 ...

  4. Maven Repository

    The usefully link for Maven Reponsitory display as below: http://mvnrepository.com/ For example, To ...

  5. 自己签发免费ssl证书

    自己制作ssl证书:自己签发免费ssl证书,为nginx生成自签名ssl证书 这里说下Linux 系统怎么通过openssl命令生成 证书. 首先执行如下命令生成一个keyopenssl genrsa ...

  6. 8个主要的Velocity语法使用说明

    8个主要的Velocity语法使用说明,分别是:Velocity表达式,Velocity注释,Velocity循环,Velocity条件判断,Velocity赋值,Velocity调试,Velocit ...

  7. zk master-slaver机制

    1.基本概念 >>zookeeper handler (zk句柄)有点类似文件句柄,打开一个文件就保持了一个文件句柄!同样的道理: 建立一个到zk server的session就会有一个z ...

  8. JS分页方法

    /** maxpage 最大页数 */function gotoPage(maxpage){         var gotoPage = document.getElementById(" ...

  9. swift 2.x学习笔记(二)

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #008400 } p.p2 { margin: 0.0px 0. ...

  10. Mininet实验 源码安装Mininet

    参考:MiniNet实验1 安装命令: sudo apt-get update sudo apt-get upgrade sudo apt-get install git(安装过git就可以忽略此步) ...