惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
T
Threatpost
Latest news
Latest news
N
News | PayPal Newsroom
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Help Net Security
Help Net Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
AI
AI
Simon Willison's Weblog
Simon Willison's Weblog
TaoSecurity Blog
TaoSecurity Blog
The Last Watchdog
The Last Watchdog
L
LINUX DO - 热门话题
Google DeepMind News
Google DeepMind News
T
Threat Research - Cisco Blogs
O
OpenAI News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
The Exploit Database - CXSecurity.com
NISL@THU
NISL@THU
Application and Cybersecurity Blog
Application and Cybersecurity Blog
S
Securelist
小众软件
小众软件
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Martin Fowler
Martin Fowler
S
SegmentFault 最新的问题
Cisco Talos Blog
Cisco Talos Blog
云风的 BLOG
云风的 BLOG
AWS News Blog
AWS News Blog
GbyAI
GbyAI
N
News and Events Feed by Topic
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
美团技术团队
Engineering at Meta
Engineering at Meta
A
About on SuperTechFans
博客园 - 三生石上(FineUI控件)
S
Schneier on Security
博客园 - 聂微东
V2EX - 技术
V2EX - 技术
T
Troy Hunt's Blog
SecWiki News
SecWiki News
S
Secure Thoughts
B
Blog RSS Feed
Hugging Face - Blog
Hugging Face - Blog
WordPress大学
WordPress大学
腾讯CDC
H
Heimdal Security Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
www.infosecurity-magazine.com
www.infosecurity-magazine.com
P
Privacy International News Feed

博客园 - 人工智能-群513704292

再出发 新的一年快开始了,学点新东西吧,从React开始(一) ECMAScript 6 Features 中文版 必须清零 彩印网的第一阶段即将收官 终于感觉掌握了一门重要的技术 程序员的命运之轮 2015年开局 2014年总结 终于理解了函数式技术 Swift来的正是时候 js的this上下文的坑 JS正则表达式进阶 JS正则表达式基本概念 前端样板资源概览及总评 C#的前世今生,学会C#还能找到高薪工作吗? CSS基本知识6-CSS字体 CSS基本知识5-CSS对齐 CSS基本知识4-CSS行模型
js的this和面向对象编程
人工智能-群513704292 · 2014-05-20 · via 博客园 - 人工智能-群513704292

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

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

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