JavaScript笔记;函数的基本特性

犹记得第一次写JS的时候,还是从定义一个函数开始。

function first() {
     ....
}

那个时候只是把函数作为一个组织代码的方式而已,过后不久,写网页应用,jquery占据了我的绝大部分时间。写的一手很溜的JQ选择器,是我自认为牛逼的开始。浮华褪尽,装逼再多,也慢慢明白需要返璞归真。因此,近来开始研习js的基本功,理解它一些不可思议的魔法。偶得心得一二。

0x00 引言

函数是JS的第一型对象,对象在JS中拥有以下特性:

可以通过字面量创建

赋值给变量,数组和其他对象的属性

作为参数传递函数

作为函数的返回值

拥有动态创建并赋值的属性

也就是说,function f(){};其实是建立了一个f的变量,指向一个函数实体。

0x01 属性

函数也是有属性的,这一点不要惊讶。正如上面那个例子提到的。function f(){};,f函数可以通过一个叫name属性,查看函数的名字:

> function f(){};
<·function f(){}
>f.name
<·"f"

而其中还有一个特别注明的属性--prototype。在很多JS的面向对象的教学上面都会提到这个给函数动态增加属性和方法的函数属性。那么这个属性是什么呢?

其实只要简单输出的一下,你就明白:

> f.prototype
<· object{}

这个属性代表的是一个对象,而如果你继续探究的话,就要说到另一个属性constructor,这个属性,稍微面向对象编程基础的人,都能明白,这个属性代表的是构造器。这个属性是函数和对象都有的,表示这个函数或者对象的构造器是那一个。

如果我们查看prototype的构造器的话,你会发现:

> f.prototype.constructor
<· function f(){}

其实就是函数f,这样你就明白为什么,prototype属性为什么能够给函数增加属性和方法了,应为这东西就是该函数本身作为构造器构造的一个对象。

prototypeconstructor谈到构造器的时候,再深入说明。需要明白的是,函数也是有属性的。

函数还有一个特殊的属性arguments,透过字面意思你也能知道,这个属性指向的是调用这个函数的参数列表。这是一个特殊的对象。它可以被当作数组遍历使用,但是他不是一个数组,所以不能使用数组的方法来操作它。

正是应为这个属性的存在,所以即使函数调用函数的参数对象是不完整的也依旧可以调用这个函数。而额外的参数,也可以通过arguments来调用使用。

0x02 上下文

上下文(context)是很多语言都有的一个概念。在Java中有着十分严格的规定和约束,但是JS中却是灵活多变。在函数的内部,上下文用this表示。在Java等面向对象语言中,this表示的是调用这个方法或者属性的对象。

例如:obj.foo = function(){return this;};这样的方式很好理解,调用obj.foo()方法,返回的是对象obj

但如果我们直接生命一个函数,没有把它赋予给任何一个对象呢?

> function f() {return this;};
> f();
<· window{...}

这样很好理解,当没有给一个函数指定上下文的时候,它的上下文是window。当然,这是在浏览器中,其他环境中我还没有研究。但远离应该是相同的,即没有赋予上下文环境的时候,赋予的最顶级的上下文环境。

将一个函数赋予给一个对象作为它的方法,是一种改变函数上下文的方式。如果我们想要动态的改变函数的上下文呢。就比如,一段代码,我们要等运行到一个结果后,才能指定这个函数的上下文来调用。这就是JS中常用的回调机制,而这个时候就要用到的函数的两个特殊的方法call()apply()

这两个方法的作用,都是为一个函数指定上下文。不同的是,调用的参数不同。

  • call:

    call方法第一个参数接收的是要指定给函数的上下文,之后的参数依次赋予函数对应的参数。

    f.call(obj, arg1, arg2, arg3)

  • apply:

    apply方法第一个参数也是接收的指定给函数的上下文,第二个参数接收的是一个数组或者arguments。将数组的元素依次匹配到函数上,或者将arguments传递给函数调用。

    f.apply(obj, [arg1, arg2, arg3])f.apply(obj, arguments)

0x03 闭包

闭包这种特性,可以理解为作用域。当然,这和Java等语言中的作用域是不一样。JS中的“作用域”更加具有函数式语言的特性。

举个栗子:

if(flag) {
    var a = 3;
} else {
    var a = 4;
}

console.log(a);

这样的代码中,a是可以被调用的。而在Java中这是会报错。这就是说明,JS中的“作用域”其实不是和Java中那样是以代码块为原子的,而是以函数为原子的。这就被称之为闭包

闭包的原则,很通俗的一条语言可以概括你的是我的,我的还是我的

即一个函数的中的资源,不可以被外部访问,但其内部可以访问。如果下面一个函数的嵌套:

    function a() {
        function b() {
            function c() {
                ...
            }
        }
    }

a外面不能调用bc,a中可以调用b,但不能调用c。依次类推,内部可以访问外部,外部不能访问内部。

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

推荐阅读更多精彩内容