1. 程式人生 > >js的this和麵向物件程式設計

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的物件弱點。

相關推薦

面向函式程式設計和麵物件程式設計的區別和使用

簡述面向函式程式設計和麵向物件程式設計的區別? 什麼時候使用面向函式程式設計?什麼時候使用面向物件程式設計? 函數語言程式設計,顧名思義,這種程式設計是以函式思維做為核心,在這種思維的角度去思考問題。 這種程式設計最重要的基礎是λ演算,接受函式當作輸入和輸出。 面向物件程式設計,這種程

面向過程程式設計和麵物件程式設計的區別

面向過程程式設計 面向過程程式設計是一種以過程為中心的程式設計思想,分析出解決問題的步驟,然後用函式把這些步驟一步一步實現。面向過程程式設計,資料和對資料的操作是分離的。 面向物件程式設計 面向物件程式設計是將事物物件化,通過物件通訊來解決問題。面向物件程式設計,資料和對資料的操作

面向過程和麵物件程式設計的的思想理解

      之所以寫這邊部落格,是因為昨日和一位電子專業的好友,聊起了這個專業問題,我卻沒有用通俗易懂的例子來解釋它們,雖然已經把C語言過了一遍,Java也學了好一段時間,但是真正去向一個外行人解釋,感覺只可意會不言傳的感覺,為此非常的懊惱。 面向過程:是一種以過程為中

面向介面程式設計和麵物件程式設計的區別

我想,對於各位使用面向物件程式語言的程式設計師來說,“介面”這個名詞一定不陌生,但是不知各位有沒有這樣的疑惑:介面有什麼用途?它和抽象類有什麼區別?能不能用抽象類代替介面呢?而且,作為程式設計師,一定經常聽到“面向介面程式設計”這個短語,那麼它是什麼意思?有什麼思想內涵?

面向過程程式設計思想和麵物件程式設計思想

一、面向過程程式設計思想 百度百科這樣解釋: “面向過程”(Procedure Oriented)是一種以過程為中心的程式設計思想。 面向過程其實是最為實際的一種思考方式,就算是面向物件的方法也是含有面向過程的思想。可以說面向過程是一種基礎的方法。它考慮的

python:面向過程和麵物件程式設計思想

一、區別 面向過程:在實現的時候,每個過程都需要一個函式 面向物件: 二、面向物件和類 類的組成:以狗為例 (1)類名:(狗) (2)類的屬性:一組資料(狗的毛色,重量等) (3)類的方法

元件化程式設計和麵物件程式設計

元件化程式設計: 在向大家詳細介紹C#元件化程式設計之前,首先讓大家瞭解下介面與元件,然後全面介紹C#元件化程式設計。 介面與元件 介面描述了元件對外提供的服務。在元件和元件之間、元件和客戶之間都通過介面進行互動。因此元件一旦釋出,它只能通過預先定義的介面來提供合理的、一致

[譯]Python提高:Python類和麵物件程式設計

原文作者:Jeff Knupp 原文連結:這裡 class是Python的基礎構建快。它是很多流行的程式和庫,以及Python標準庫的基礎依託。理解類是什麼,什麼時候使用,以及它們如何有用至關重要,這也是本文的目的。在這個過程中,我們會探討“

js的this和麵物件程式設計

    很奇怪的是很多書或資料沒有把這個事情講清楚。     關鍵就是在於沒有一個整體的思維技術模式,問題被隔離了所以反而不容易理解。     我們先看this,這是js的關鍵字,指示函式的上下文物件。     這裡問題就來了,比如: var obj = {};

return函式提前傳參和麵物件程式設計方式

function request({method,data}){f.c(data)}   function get(v){ return request({method:'GET', data:v}) } f

我眼中的-php之面向物件和麵過程程式設計

作為一位有趣又有靈魂開發者,每天可能都在處理著大量的業務邏輯,你的狀態可能每天是這樣的,請看下圖: 這樣擼程式碼固然很爽,可是你考慮過隊友的感受? 隨著時間的推移,專案的不斷迭代,團隊的不斷壯大,同時專案的複雜度也在成正比不斷增加。        通常一個專案基於成

《java程式設計思想》--物件初始化和麵物件特性

1.java類的初始化順序 (1).一個類中,初始化順序由變數在類中的宣告定義順序決定,成員變數初始化在方法呼叫之前,包括構造方法。 (2).靜態變數在整個儲存區只保留一份拷貝,本地變數不能使用靜態關

面向過程程式設計,面向物件程式設計和麵切面程式設計理解

面向過程(Procedure Oriented)是一種以過程為中心的程式設計思想。這些都是以什麼正在發生為主要目標進行程式設計,不同於面向物件的是誰在受影響。與面向物件明顯的不同就是封裝、繼承、類。 面向物件程式設計(Object Oriented Progr

Python基礎-面向物件和麵過程程式設計區別

前言 OOP,是一種程式設計思想。OOP把物件作為程式的基本單元,一個物件包含了資料和操作資料的函式。哈哈哈,學Python、Java的人表示很開心。 面向過程的程式設計 把計算機程式視為一系列的命令集合,即一組函式的順序執行。為了簡化程式設計,面向過程把

JavaScript面向物件程式設計和麵過程程式設計

JavaScript程式設計中多數情況是面向過程程式設計,但有時候為了更好地封裝重用。面向物件思想來程式設計更為有用。 雖然現前端都開始流行MVC思想的js框架,但並不是說js沒用了,學好js對於學習js前端框架,jquery,等都是非常有幫助的。 好了,閒話不說,下面用一

CMM模型,結構化開發方法和麵物件開發方法的比較,

CMM模型 一、CMM簡介 CMM,英文全稱為Capability Maturity Model for Software,即:軟體成熟度模型。 CMM的核心是把軟體開發視為一個過程。它是對於軟體在定義、實施、度量、控制和改善其軟體過程的實踐中各個發展階段的描述。 根據這一原則對軟體開發和維護進行過程

建構函式與原型鏈和麵物件的學習(三)

下面對面向物件寫個小案例(紅綠燈) 上面是原圖 用來來實現點選圖片,紅綠燈的顏色改變,控制背景圖片的定位來改變 點選一下 就是要完成上面的效果 如果只要實現一個 CSS div{ width: 335px; height: 890px; margin-left:

建構函式與原型鏈和麵物件的學習(二)

  這節對原型鏈的學習 最下面有所有的會用到的完整js程式碼 講解 每一個函式都有一個屬性叫做prototype,指向一個物件(不是函式就沒有這個屬性),當這個建構函式被new的時候,他的每一個例項的__proto__屬性,也指向這個物件    &nbs

建構函式與原型鏈和麵物件的學習(一)

下面文章所有的例子(關於什麼是建構函式) 例子中完整的js程式碼在文章最下面 第一個例子 function fun(){                 this.na

028_面向物件_01_面向過程和麵物件的本質區別

一、本質   a)面向過程(Procedure Oriented):是一種以過程為中心的程式設計思想。這些都是以什麼正在發生為主要目標進行程式設計,不同於面向物件的是誰在受影響。與面向物件明顯的不同就是封裝、繼承、類。   b)面向物件(Object Oriented,OO):是軟體開發方法。面向物件的概