很奇怪的是很多书或资料没有把这个事情讲清楚。

关键就是在于没有一个整体的思维技术模式,问题被隔离了所以反而不容易理解。

我们先看this,这是js的关键字,指示函数的上下文对象。

这里问题就来了,比如:

            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,直接使用返回对象。

            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,所以我们在内部,直接定义对象返回,做成真正的“构造函数”

            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的对象弱点。

最新文章

  1. UVa11082 Matrix Decompressing(最小费用最大流)
  2. vbox导入虚拟电脑网卡MAC问题
  3. UCenter 通信失败 和 无法同步登陆的调试方法
  4. 实现简易的android 直播技术
  5. [HDU5907]Find Q(水)
  6. cxx-generator JS绑定工具
  7. Keil uCos 2.52 stm32 【worldsing笔记】
  8. c#隐式转换之有符号位转换
  9. Codeforces 486C Palindrome Transformation(贪心)
  10. Python字符串处理NoneType的处理
  11. kiss框架学习
  12. Java跨域设置
  13. 4、File类之获取方法
  14. 运用GRASP原则来做uml交互类图-------pos机实例
  15. ffmpeg中AVBuffer的实现分析
  16. python有序字典OrderedDict()
  17. 安装crf++的python包
  18. JS 获取浏览器的宽和高
  19. t检验,T Test (Student’s T-Test)
  20. 很清晰的解读i2c协议

热门文章

  1. js正则表达式图形化工具-rline
  2. 请将项目文件中的“AutoGenerateBindingRedirects”属性设置为 true 警告!!!
  3. 元首的愤怒 SharePoint Apps
  4. SharePoint 2013 网站搜索规则的使用示例
  5. elk查询语法
  6. Android Gson的使用总结
  7. XML 概述 (可扩展标记语言)
  8. CoreLocation定位技术
  9. mac osx vi 设置tab 四个空格
  10. VS的安装