胡说JS系列-JavaScript函数类型

回到了自己的家乡,期待中有感觉到了很多的陌生,一个有“故事”的环境中,你我是否“孤独”!

函数的类型

在我看来function共有三种类型,作为对象使用,处理业务以及穿件object的实例对象。跟这三种用法相对应的有三种子类型,分别是对象的属性、变量(包括参数)和创建出来的object类型实例对象的属性。这三种子类是相互独立的,而且也很容易区分。但是,我们刚刚接触的时候很容易混淆。

1.function 作为对象来使用

这种情况下,function对象的子类型就是对象自己的属性,这时通过操作符“.”(或者方括号操作符)使用,示例如下:

function book(){}
book.price=999;
book["getPrice"]=function(){
    return this.price;
}
console.log(book.getPrice()); //输出结果:999

我很少碰到function来作为object类型的对象来使用。

2.funciton 用于处理业务

这种情况下,function的子类型就是自己定义的局部变量(包括参数),这时的变量实在方法被调用时通过变量作用域链来管理的。
关于变量我之前的文档中有涉及到,这里就不过多的说明了。

3.function 用于创建对象

这种情况下,对应的子类型是使用function创建实例对象的属性(很常用),主要包括在function中通过this添加属性,以及创建完成之后实例对象自己添加的属性。另外,还可以调用function的prototype属性对象所包含的属性,示例如下:

function Car(color,displacement){
    this.color = color;
    this.displacement = displacement;
}
Car.prototype.logMessage = function(){
  console.log(this.color+","+this.displacement);  
};
var car = new Car("yellow","2.4T");//看看是不是类似构造函数?哈哈

这个例子中创建的car对象就包含有color和displacement两个属性,而且还可以调用Car.prototype的logMessage方法。当然,创建完之后还可以使用点操作符给创建的car对象添加或者修改属性,也可以使用delete删除其中的属性,示例如下:

function Car(color,displacement){
    this.color = color;
    this.displacement = displacement;
}
//所有创建出来的car都有该方法
Car.prototype.logMessage = function(){
  console.log(this.color+","+this.displacement);  
};
var car = new Car("yellow","2.4T");//看看是不是类似构造函数?哈哈
//给car对象添加属性
car.logColor = function(){
  console.log(this.color);  
};
//完成调用测试
car.logColor();//输出结果: yellow
car.color = "red";
car.logColor();//输出结果:red
delete car.color;//删除属性
car.logColor();//输出结果:undefined

代码分析:

在创建完car对象之后,又给它添加了logColor的方法,可以打印car的color属性。添加完logColor方法后直接调用就可以打印出car原来的color属性值(yellow)。然后,将其修改为red,在打印出了red。最后,使用delete删除car的color的属性,这时在调用logColor方法会打印出undefined

其实跟我的注释说明一致!!!

三种子类型的关系

function的三种子类型是相互独立的,他们只能在自己所对应的环境中使用而不能相互调用,示例如下:

function log(msg){//第二种业务处理
    console.log(msg);
}
function Bird(){
    var name = "kitty";
    this.type = "pigeon";
    this.getName = function(){
        return this.name;//创建的对象没有name属性
    }
}
Bird.color = "white";//第一种object类型的对象
Bird.getType = function(){//第一种object类型的对象
    return this.type;
};
Bird.prototype.getColor = function(){//第三种创建对象
    return this.color;
}
var bird = new Bird();
log(bird.getColor());// undefined
log(bird.getName()); // undefined
log(bird.getType()); // undefined

Bird 作为对象时包含 color 和 getType 两个属性,作为处理业务的函数是包含一个名为name的局部变量,创建的实例对象bird具有type和getName两个属性,而且还可以调用Bird.prototype的getColor属性,getColor也可以看作bird的属性。

用 法 子 类 型
对象(Bird) color 、getType
处理业务(Bird方法) name
创建实例对象(bird) type、getName、(getColor)

每种用法中所定义的方法只能调用相对应所对应的属性,而不能交叉调用,从对应关系中可以看出,getName、getColor和getType三个方法中无法获取到值,大家再仔细分析一下!

另外,getName和getColor是bird的属性方法,getType是Bird的属性方法,如果用Bird对象调用getName或getColor方法或者使用bird对象调用getType方法都会抛出找不到的错误。

三种子类型不可以相互进行调用之外,还有一种情况也非常重要:那就是对象的属性并没有继承的关系。

function obj(){}
obj.v=1;
obj.func = {
    logV : function(){
        console.log(this.v);
    }
}
obj.func.logV();

代码分析:

这个例子中的obj是作为对象使用的,obj是有一个属性v和一个对象属性func,func对象中又有一个logV方法,logV方法用于打印对象的v属性。这里需要特别注意:

logV方法打印的是func对象的v属性,但是func对象中并没有v属性,所以最后结果是undefined。

这个例子中,虽然obj对象中包含v属性,但是由于属性不可以继承,所以obj的func属性对象中的方法不可以使用obj中的属性v.

请大家一定要记住,并且不要和prototype的继承以及变量作用域链相混淆

关联三种子类型

三种子类型本来是相互独立、各有各的使用环境的,但是,有一些情况下需要操作不属于自己所对应环境的子类型,这时就需要使用一些技巧来实现了。

约定如下

  • function 作为对象使用时记作 O(Object)
  • 作为函数使用时记作 F(Function)
  • 创建出来的对象实例记作 I(Instance)
  • op(object property)
  • v(variable)
  • ip(instance property)
op v ip
O 直接调用 在函数中关联到O的属性 不可调用
F 使用O调用 直接调用 不可调用
I 使用O调用 在函数中关联到I的属性 直接调用
  • 纵向表头表示function的不同用法

  • 横向表头表示三种类型,表格的主体表示在function相应用法中调用各种子类的方法。

    因为function创建的实例对象在创建之前还不存在,所以function作为方法(F)和作为对象(O)使用时无法调用function创建的实例对象的属性(ip)。调用参数可以在函数中将变量关联到相应的属性,调用function作为对象(O)时的属性可以直接使用 function 对象来调用

function log(msg){
    console.log(msg);
}
function Bird(){
    //私有属性
    var name = "kitty";
    var type = "pigeon";
    //将局部变量name关联到新创建的对象的getName,setName属性方法
    //闭包可以使用局部变量
    //公有属性
    this.getName = function(){
        return name;
    }
    this.setName = function(n){
        name = n;
    }
    //将局部变量type关联到Bird对象getType属性方法
    //静态属性
    Bird.type = function(){
        return type;
    }
    //在业务处理中调用Bird对象的color属性
    log(Bird.color);//输出结果: white,F调用op
    
}
Bird.color = "white";// 代表 O
//在创建出的实例对象中调用Bird对象的color属性
Bird.prototype.getColor = function(){//I
    return Bird.color;//OP
}
var bird = new Bird(); // 创建实例 I
log(bird.getColor()); // 输出结果:white , I 调用 op
log(bird.getName());// 输出结果:kitty , I 调用 v 局部变量
log(Bird.getType());// 输出结果:pigeon , O 调用 v 局部变量
bird.setName("petter");  // I 调用 v
log(bird.getName());// 输出结果:petter , I 调用 v 局部变量

好好分析上述的代码,非常经典的,了解三种子类型的不同环境用法中交叉调用的方法

附录:“公有属性” “私有属性” 和 “静态属性”

上面的示例中我们涉及到了公有属性、私有属性和静态属性的说明,由于JS并不是基本类而是基于对象的语言,因此JS本身并没有这些概念。

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

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,036评论 1 32
  • 函数和对象 1、函数 1.1 函数概述 函数对于任何一门语言来说都是核心的概念。通过函数可以封装任意多条语句,而且...
    道无虚阅读 4,351评论 0 5
  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,642评论 2 9
  • 第3章 基本概念 3.1 语法 3.2 关键字和保留字 3.3 变量 3.4 数据类型 5种简单数据类型:Unde...
    RickCole阅读 5,037评论 0 21
  • 原文:Spring各类集合注入摘要: 我们常在Spring的Bean中注入各种基本类型的值和对象引用,如果需要注入...
    cmlong_阅读 566评论 0 0