js的this和面向对象编程
很奇怪的是很多书或资料没有把这个事情讲清楚。
关键就是在于没有一个整体的思维技术模式,问题被隔离了所以反而不容易理解。
我们先看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和面向对象编程的更多相关文章
- JS - ES5与ES6面向对象编程
1.面向对象 1.1 两大编程思想 1.2 面向过程编程 POP(Process-oriented programming) 1.3 面向对象编程 OOP (Object Oriented Progr ...
- JS 学习笔记 (七) 面向对象编程OOP
1.前言 创建对象有很多种方法,最常见的是字面量创建和new Object()创建.但是在需要创建多个相同结构的对象时,这两种方法就不太方便了. 如:创建多个学生信息的对象 let tom = { n ...
- JS面向对象编程(一):封装
js是一门基于面向对象编程的语言. 如果我们要把(属性)和(方法)封装成一个对象,甚至要从原型对象生成一个实例,我们应该怎么做呢? 一.生成对象的原始模式 假定把猫看 ...
- 快速理解JavaScript面向对象编程—原型
总的来说js语言就是门面向对象编程的语言,对象这个概念几乎贯穿了整个js的学习. 对象 创建对象两种方法:(若要生成对象实例必须调用构造函数) 1.var obj = {name:"jer& ...
- 带你一分钟理解闭包--js面向对象编程
上一篇<简单粗暴地理解js原型链--js面向对象编程>没想到能攒到这么多赞,实属意外.分享是个好事情,尤其是分享自己的学习感悟.所以网上关于原型链.闭包.作用域等文章多如牛毛,很多文章写得 ...
- Js面向对象编程
Js面向对象编程 1. 什么是面向对象编程? 我也不说不清楚什么是面向对象,反正就那么回事吧. 编程有时候是一件很快乐的事,写一些小游戏,用编程的方式玩游戏等等 2. Js如何定义一个 ...
- js原生设计模式——3简单工厂模式\js面向对象编程实例
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- JS面向对象编程(进阶理解)
JS 面向对象编程 如何创建JS对象 JSON语法声明对象(直接量声明对象) var obj = {}; 使用 Object 创建对象 var obj = new Object(); JS对象可以后期 ...
- JavaScript--我发现,原来你是这样的JS:面向对象编程OOP[2]--(创建你的那个对象吧)
一.介绍 我们继续面向对象吧,这次是面向对象编程的第二篇,主要是讲创建对象的模式,希望大家能从博客中学到东西. 时间过得很快,还是不断的学习吧,为了自己的目标. 二.创建对象 1.前面的创建对象方式 ...
随机推荐
- [读码][js,css3]能感知鼠标方向的图片遮罩效果
效果图: 无意间看到过去流行的一个效果:[能感知鼠标方向的图片遮罩效果]近来不忙,就仔细的看了一看看到后来发现,网上有好多版本,谁是原著者似乎已经无法考证.读码就要读比较全面的,读像是原著的代码.代码 ...
- FusionCharts的使用方法(超详细)
今天统计价格变化规律的时候找到的一个很好的文档,很详细 一.简介 Ø FusionCharts 是InfoSoft Global 公司的一个产品,InfoSoft Global 公司是专业的Flash ...
- 12种不适宜使用的javascript语法
1. == (o゜▽゜)o☆[BINGO!] Javascript有两组相等运算符,一组是==和!=,另一组是===和!==.前者只比较值的相等,后者除了值以外,还比较类型是否相同. 请尽量不要使用前 ...
- 关于安卓APP的启动界面
刚学安卓App开发的朋友们,可能会遇到一个问题,就是人家的App刚进入会有一个页面出现一会儿后消失, 这个页面可以用来打广告,也可以声明App的主题,所以说这个启动页面至关重要,接下来,我把我的代 ...
- Android Bitmap占用内存计算公式
Android对各分辨率的定义 当图片以格式ARGB_8888存储时的计算方式 占用内存=图片长*图片宽*4字节 图片长 = 图片原始长 (设备DPI/文件夹DPI) 图片宽 = 图片原始宽(设备D ...
- IE10 和 Chrome50 对日期 new Date() 支持的区别
IE10 和 Chrome50 对日期 new Date() 支持的区别: new Date('2016-06-18'); // IE10 不通过.Chrome 通过 new Date('2016/0 ...
- (四)新建Maven项目
我们以简单的helloworld来作为入门的实例,有些人说掌握了helloworld你就掌握了这门技术的一半了,对于maven来说,你掌握helloworld,你可能还稀里糊涂的. 1.从maven模 ...
- Linq专题之提高编码效率—— 第二篇 神一样的匿名类型
说起匿名类型,我们都知道这玩意都是为linq而生,而且匿名类型给我们带来的便利性大家在实战中应该都体会到了,特别适合于一次性使用,临时 使用这些场景,虽然说是匿名类型,也就是说是有类型的,只是匿名了而 ...
- 测试几个xml的问题
使用sql server的时候,免不了与xml的参数打交道,xml大多数时候都给我们的程序带来方便,但是也有些时候会有变量赋值不通过的时候.(当然罗,如果你本身xml都通不过 xml spy 之类软件 ...
- MySQL的loose index scan
众所周知,InnoDB采用IOT(index organization table)即所谓的索引组织表,而叶子节点也就存放了所有的数据,这就意味着,数据总是按照某种顺序存储的.所以问题来了,如果是这样 ...