引用类型之Function类型

对于面向对象编程的语言来说,对象是很重要的一个概念,而对于函数来说,每个函数实际上都是对象,每个函数都是Function类型的实例,而且与其他引用类型一样具有属性和方法。

函数声明与函数表达式

通常有三种声明函数的方法

  1. 使用函数声明语法
function sum(num1, num2) {
return num1 + num2;
}

这也是最常用的方法

  1. 使用函数表达式定义函数
var sum = function (num1, num2) {
return num1 + num2;
};

可能会注意到function关键字后面没有函数名,这是因为使用函数表达式定义函数时,通过变量sum就可以引用函数

  1. 使用Function构造函数
var sum = new Function("num1", "num2", "return num1 + num2");

但是非常不推荐这种写法,因为这种语法会导致解析两次代码(第一次解析ECMAScript代码,第二次解析传入构造函数的参数)从而影响性能

关于变量提升

对于1,2两种声明函数的方法有什么不同呢?看下面这个例子

// 使用函数声明创建函数
console.log(sum(10,10));  //会打印出20
function sum(num1, num2) {
  return num1 + num2;
};

// 使用函数表达式创建函数
console.log(add(10,10)); //会报错
var add = function(num1, num2) {
  return num1 + num2;
};

实际上,解析器在执行环境中加载数据时,解析器会率先读取函数声明,并使其在执行任何代码之前可用,而至于函数表达式,则必须等到解析器执行到它所在的代码行才会真正被解释执行。

函数内部属性

在函数内部,有两个特殊的对象:argumentsthis

arguments是一个类数组对象,包含着传入函数的所有参数,之前在基础算法的时候已经讲过。但是arguments还有一个名叫callee属性,该属性是一个指针,指向拥有arguments对象的函数。具体用法之前写过了,看这里

另一个比较特殊的对象就是this了,关于this知乎上@方方老师这篇文章讲的特别好

函数的属性和方法

因为在ECMAScript中函数是对象,因此函数也有属性和方法。

每个函数包含两个属性:lengthprototype

length表示函数接受的参数的个数

function sayName(name) {
  console.log(name);
}

function sum(sum1, sum2) {
  return num1 + num2;
}

function sayHi() {
  console.log("Hi!");
}

console.log(sayName.length);  //1
console.log(sum.length);      //2
console.log(sayHi.length);    //0

另一个属性prototype是保存引用类型所有实例方法的真正所在,比如toString()valueOf()等方法都保存在prototype名下,prototype在实现继承时非常重要,下一篇我们再讲。

每个函数都包含两个非继承来的方法:apply()call()

apply()call()都是在特定的作用域中调用函数,等于设置函数体内this的值,他们的区别在于:
apply()接受两个参数:一个是在其中运行函数的作用域,另一个是参数数组,既可以是Array实例,也可以是arguements对象。
call()第一个参数和apply()一样,但是传递参数的时候,必须逐个例举出来。

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

function callSum1(num1, num2) {
  return sum.apply(this, arguments);   //传入arguments字符串
}

function callSum2(num1, num2) {
  return sum.apply(this, [num1,num2]);  //传入数组
}

function callSum3(num1, num2) {
  return sum.call(this, num1, num2);   //使用call必须把参数列举出来
}

console.log(callSum1(10,10));   //20
console.log(callSum2(10,10));   //20
console.log(callSum3(10,10));   //20

既然apply()call()的参数有作用域,那么是用来干什么的呢?看下面的例子:

window.color = "red";
var 0 = { color: "blue" };

function sayColor() {
  console.log(this.color);
}

sayColor();                //red
sayColor.call(this)        //red
sayColor.call(window)      //red
sayColor.call(o)           //blue

是不是this的值又懵了?如果懵了,就翻上去看方方老师那篇文章。
没错,apply()call()的作用就是扩充函数的作用域

大概就是这么多了,书上这一章的内容我反复看了好几遍才理解,所以学习哪有什么捷径,无他,唯手熟尔
那么,聪明的你,看完之后懂了没有?
下一篇准备讲原型

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容