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

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

我们先看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的对象弱点。

js的this和面向对象编程的更多相关文章

  1. JS - ES5与ES6面向对象编程

    1.面向对象 1.1 两大编程思想 1.2 面向过程编程 POP(Process-oriented programming) 1.3 面向对象编程 OOP (Object Oriented Progr ...

  2. JS 学习笔记 (七) 面向对象编程OOP

    1.前言 创建对象有很多种方法,最常见的是字面量创建和new Object()创建.但是在需要创建多个相同结构的对象时,这两种方法就不太方便了. 如:创建多个学生信息的对象 let tom = { n ...

  3. JS面向对象编程(一):封装

    js是一门基于面向对象编程的语言.      如果我们要把(属性)和(方法)封装成一个对象,甚至要从原型对象生成一个实例,我们应该怎么做呢?  一.生成对象的原始模式            假定把猫看 ...

  4. 快速理解JavaScript面向对象编程—原型

    总的来说js语言就是门面向对象编程的语言,对象这个概念几乎贯穿了整个js的学习. 对象 创建对象两种方法:(若要生成对象实例必须调用构造函数) 1.var obj = {name:"jer& ...

  5. 带你一分钟理解闭包--js面向对象编程

    上一篇<简单粗暴地理解js原型链--js面向对象编程>没想到能攒到这么多赞,实属意外.分享是个好事情,尤其是分享自己的学习感悟.所以网上关于原型链.闭包.作用域等文章多如牛毛,很多文章写得 ...

  6. Js面向对象编程

    Js面向对象编程 1.     什么是面向对象编程? 我也不说不清楚什么是面向对象,反正就那么回事吧. 编程有时候是一件很快乐的事,写一些小游戏,用编程的方式玩游戏等等 2.     Js如何定义一个 ...

  7. js原生设计模式——3简单工厂模式\js面向对象编程实例

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  8. JS面向对象编程(进阶理解)

    JS 面向对象编程 如何创建JS对象 JSON语法声明对象(直接量声明对象) var obj = {}; 使用 Object 创建对象 var obj = new Object(); JS对象可以后期 ...

  9. JavaScript--我发现,原来你是这样的JS:面向对象编程OOP[2]--(创建你的那个对象吧)

    一.介绍 我们继续面向对象吧,这次是面向对象编程的第二篇,主要是讲创建对象的模式,希望大家能从博客中学到东西. 时间过得很快,还是不断的学习吧,为了自己的目标. 二.创建对象 1.前面的创建对象方式 ...

随机推荐

  1. SharePoint 2013 图文开发系列之自定义字段

    SharePoint使用的优势,就在于开箱即用.快速搭建,SharePoint自身为我们提供了很多字段类型,已经很丰富了.但是,在实际应用中,我们还需要一些功能特殊的字段,下面,我们简单介绍下字段的开 ...

  2. AD RMS 配置指南 附结合SharePoint使用

    本文的 RMS配置 是独立安装的配置手册,如果要和SharePoint结合使用可以作为参考指南. SharePoint安装可参考 点击链接 同样可提供给Office使用,当然Exchange也可以使用 ...

  3. Linux系统安装NoSQL(MongoDB和Redis)步骤及问题解决办法

    ➠更多技术干货请戳:听云博客 如下是我工作中的记录,介绍的是linux系统下NoSQL:MongoDB和Redis的安装过程和遇到的问题以及解决办法: 需要的朋友可以按照如下步骤进行安装,可以快速安装 ...

  4. iOS 实用博客整理(连载版)

    iOS 实用博客整理(连载版) 本博客为本人觉得不错的博客的暂存地,并不是本人所写. 1.iOS开发 如何适配iOS10? 2.UIWebView和WKWebView的比较和选择 3. 如何快速的开发 ...

  5. IOS网络请求的一些需要记录的info设置

    info.plist文件: <key>NSExceptionDomains</key> <dict> <key>appapi.700bike.com&l ...

  6. 让我们来谈谈JDBC

    1.JDBC     1)JDBC简介         - JDBC就是Java中连接数据库方式         - 我们可以通过JDBC来执行SQL语句.       2)获取数据库连接   - j ...

  7. #数据技术选型#即席查询Shib+Presto,集群任务调度HUE+Oozie

    郑昀 创建于2014/10/30 最后更新于2014/10/31   一)选型:Shib+Presto 应用场景:即席查询(Ad-hoc Query) 1.1.即席查询的目标 使用者是产品/运营/销售 ...

  8. ORACLE临时表空间总结

    临时表空间概念 临时表空间用来管理数据库排序操作以及用于存储临时表.中间排序结果等临时对象,当ORACLE里需要用到SORT的时候,并且当PGA中sort_area_size大小不够时,将会把数据放入 ...

  9. 统计文件种类数+获取子shell返回值的其它方法

    前言 只是作为一个shell的小小练习和日常统计用,瞎折腾的过程中也是摸到了获取子shell返回值的几种方法: 肯定还有别的方法,跟进程间的通信相关,希望你能提出建议和补充,谢谢~ 完整程序: #! ...

  10. 烂泥:haproxy学习之https配置

    本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb. 在前一段时间,我写了几篇有关学习haproxy的文章.今天我们再来介绍下haproxy ...