JavaScript中具名函数的多种调用方式(2)
以函数中有无this来讨论。没有this时返回一个空的对象{},有this时返回一个非空对象。
下面是一个没有this的函数
1 2 3 4 5 6 7 8 9 10 | // 返回值是基本类型 function fun() { return "jack" ; } var c = new fun(); for ( var atr in c) { alert(atr); } alert(c); //[object Object] |
返回值c不是"jack", 从for in执行后没有输出任何属性可以看出 c 是一个空的对象{}。
再看看有this的函数,函数中有this实际上是在写一个类。但由于js的灵活性,造成了许多诡异的写法。
1 2 3 4 5 6 7 8 9 10 11 | // 返回值是基本类型 function fun() { this .name = "tom" ; return "jack" ; } var c = new fun(); for ( var atr in c) { alert(atr); //name } alert(c.name); //tom |
返回值也不是"jack",for in输出了name属性,最后一句输出了tom,说明返回值 c 是一个非空对象。这里的return "jack"压根没起作用。所以当函数返回值是内置类型(基本类型)时,用new方式调用函数将会导致错误的结果 。
那么当函数返回值是一个对象,数组,函数呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // 不含this,返回值是一个对象 function fun() { //组装一个对象 var obj = {}; obj.name = 'andy' ; obj.age = 20; obj.msg = function (){} return obj; } var c = new fun(); for ( var atr in c) { alert(atr); //name,age,msg } alert(c.name); //andy |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // 含this,返回值是一个对象 function fun() { this .sex = "man" ; //组装一个对象 var obj = {}; obj.name = 'andy' ; obj.age = 20; obj.msg = function (){} return obj; } var c = new fun(); for ( var atr in c) { alert(atr); //name,age,msg } alert(c.name); //andy<br> |
两段的输出结果是一样的,c都含有name,age,msg属性而不含sex属性。说明当返回值是对象类型(对象,数组,函数)时,new不会用this去构造对象,而直接返回组装的对象。
这种方式实际上是工厂方式,在应用中更多的程序员把函数名首字母大写,让它看起来更像一个类。
1 2 3 4 5 6 7 8 9 10 11 12 | /** * 定义一个函数Car */ function Car(color,doors) { var car = {}; car.color = color; car.doors = doors; car.msg = function (){ alert( "This is a " + this .color + " car, there are " + this .doors + " doors." ); } return car; } |
定义了函数Car,函数内创建了一个空对象,添加了一些属性和方法后返回。 以下是两种创建方式
1 2 3 4 5 6 7 | // 方式1 var c1 = Car( 'red' ,2); c1.msg(); // 方式2 var c2 = new Car( 'black' ,4); c2.msg(); |
方式1是函数调用,方式2是new。方式2把Car当成了一个类,但实际上并不是(Car的this和prototype都未挂属性,方法)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端