js的this和面向对象编程
很奇怪的是很多书或资料没有把这个事情讲清楚。
关键就是在于没有一个整体的思维技术模式,问题被隔离了所以反而不容易理解。
我们先看this,这是js的关键字,指示函数的上下文对象。
这里问题就来了,比如:
1 2 3 4 5 6 7 8 9 10 11 | var obj = {}; obj.name = 'test' ; obj.output = function () { console.log( this .name); }; obj.output(); |
this指定了上下文对象,当然如果没有指定就会指定到全局变量,window,这就是问题的根源所在。所以最好的解决方案,就是使用'use strict'严格模式,一但出错,比较容易定位问题。
在不用严格模式下,我们看看问题出现在哪里?
重命名变量时:
比如上面,console.log(obj.name),不用this的话,那么在其它代码里obj被另外变量定义,明显要出错。但用了this,代码环境一变就出问题。
比如我们把这个对象重构成构造函数:
function Obj(name) {
....
都要使用this关键字。
但是构造函数也是个函数,稍不注意就会当成普通函数调用。不加new,变成这样。
Obj('test')...
这时构造函数被错误运行,而它竟争不会出错,为什么呢?在非严格模式下,构造函数的this指向了全局的window,这就是JS最大的缺陷。不仅不能得到正确的运行结果,还污染了全局。在大量的JS里,误调用一个构造函数就是灾难性的结果。
为什么面向对象的程序比如C#,Java不会有这个问题?因为它们使用class关键字,class在定义阶段无法使用(除非明确定义的static属性和方法)
可见,JS的这个严重的this,不仅是全局变量的问题,还影响了整个构造函数的面向对方方式编程,所以安全的方式写构造函数是必须的,就是不用new,也能构造。
当然'use strict'只是治标。治本就是要让new 和不new都得到一致的结果。
JS的构造函数,如果直接运行,那么返回结果就是对象,this定义的对象被抛弃,很特别的一点。所以干脆就不用定义this用new,直接使用返回对象。
1 2 3 4 5 6 7 8 9 10 11 12 | function pClass() { this .Name = 'test' ; this .output = function () { console.log( this .Name); } return new pClass(); } var p1 = pClass(); var p2 = new pClass(); p1.output(); p2.output(); |
不用new,倒是对了,第一个问题得到解决,但如果再new就会变成嵌套调用。出错。很明显,出错是因为this,所以我们在内部,直接定义对象返回,做成真正的“构造函数”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function pClass() { return { Name: 'test' , output: function () { console.log( this .Name); } } } var p1 = pClass(); var p2 = new pClass(); p1.output(); p2.output(); |
这问题又来了,直接返回对象避免了this的问题,但明显重复,比如p1,p2使用了两个实例的output方法,这是不可以容忍的。
所以这就导致了JS在处理对象的创建方面无法提供有效的机制,this和new不匹配,彻底的解决方案就是ES6,引入class关键字,否则的话,不管怎么创建都没有完美的解决方案,而且代码啰嗦。
在ES5上,次好的解决方案是:
1.引入'use strict',防止错误的构造函数及this
2.构造函数首字母大写,其它的一律驼峰,通过命名来区分
3.创建对象一律使用new,并使用简单的prototype模式
4.非new形式尽量使用module模式
5.最关键的地方,JS对象就不是长项,面向对象编程也并非最佳方式,应该优先考虑组合模式,把对象和方法体分开,这从根源上解决JS的对象弱点。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 单线程的Redis速度为什么快?
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
2013-05-20 关于技术的学习及批判
2013-05-20 Vision of Scala 3
2013-05-20 软件开发平台正在面临一次重大的升级,java, net比起来简直弱爆了,新型的Html5+JS+JSON开发平台正在形成
2010-05-20 Flash已死终成现实,Adobe亲手埋葬Flash,并公开支持Html5