JavaScript面向對象入門

来源:https://www.cnblogs.com/Java3y/archive/2018/03/01/8487892.html
-Advertisement-
Play Games

什麼是JavaScript? 我們可以從幾個方面去說JavaScript是什麼: 基於對象 javaScript中 內置了許多對象 供我們使用【String、Date、Array】等等 javaScript也 允許我們自己自定義對象 事件驅動 當用戶觸發執行某些動作的時候【滑鼠單機、滑鼠移動】, j ...


什麼是JavaScript?

我們可以從幾個方面去說JavaScript是什麼:

  • 基於對象
    • javaScript中內置了許多對象供我們使用【String、Date、Array】等等
    • javaScript也允許我們自己自定義對象
  • 事件驅動
    • 當用戶觸發執行某些動作的時候【滑鼠單機、滑鼠移動】,javaScript提供了監聽這些事件的機制。當用戶觸發的時候,就執行我們自己寫的代碼。
  • 解釋性語言
    • [x] javaScript代碼是由瀏覽器解析的,並不需要編譯。
  • 基於瀏覽器的動態交互技術
    • 既然javaScript是由瀏覽器解析的,那麼它肯定要基於瀏覽器。 javaScript讓網頁變得更加“靈活""
  • 弱類型
    • [x] 像java、c++等編譯型語言,要先定義變數,後使用。javaScript能夠直接使用,不需要先定義

JavaScript變數類型

javaScript變數可分為三種類型:

  • 基本類型【number、string、boolean】
    • javaScript是弱類型語言,在運行的時候才知道具體的類型是什麼。所有類型都用var來修飾。
  • 特殊類型【null、undefined】
    • 當定義了變數,沒有任何賦值的時候,該變數就是undefined類型
  • 複合類型【數組、對象、函數】

javaScript對象的類型

在JavaScript中對象的類型可分為4種:

  • 內置對象【String、Math、Array】
  • 自定義對象【程式員自己創建的對象】
  • 瀏覽器對象【windows、document、history、status等等與瀏覽器相關的對象】
  • ActiveXObject(XMLHttpRequest)對象【非同步對象,使用AJAX用到的對象,使用該對象與伺服器進行非同步交互】

定義函數三種方式

函數是屬於特殊類型的一種,在另外一篇博文已經講解了創建對象、創建類的幾種方式,可參考http://blog.csdn.net/hon_3y/article/details/69362242

值得註意的是:javaScript定義函數的時候,參數的類型是不用聲明的!

正常方式

下麵就定義了一個名稱為mysum的函數

        function mysum(num1,num2){
            return num1 + num2;
        }
        var myresult = mysum(100,200);
        alert("myresult="+myresult);

Function定義

在JavaScript中, 一切皆是對象,函數也可以用一個對象來代表:Function,我們可以使用Function來創建對象:

函數參數全都是字元串,最後一個字元串是方法體


        var youresult = new Function("num1","num2","return num1+num2");
        alert( youresult(1000,2000) );

由於這種方法寫起來並不好些,可讀性也不太好,因此很少使用【不推薦使用】


匿名創建函數

其實這種和第一種差不多,只不過是將一個無名的函數賦值給一個變數。那麼這個變數就代表了這個函數。



var theyresult = function(num1,num2){
                            return num1 + num2; 
                         }
        alert( theyresult(10000,20000) );

theyresult這個變數就代表了函數。


創建對象

方式①

直接使用new Object()


  var obj = new Object();

方式②

使用空的{}大括弧

    var obj2 = {};

測試

這裡寫圖片描述

增加屬性,訪問屬性

我們要為創建的對象增加屬性和訪問屬性的值

使用.操作符增加屬性

JavaScript是弱類型的語言,可以動態的添加屬性。


    obj.age = 20;
    obj.name = "zhongfucheng";
    obj.say = function () {
        alert("hello");
    };

測試

這裡寫圖片描述


使用.操作符訪問屬性


    var aa = obj.age;
    var bb = obj.name;

測試

這裡寫圖片描述


使用[]操作符訪問屬性


    var aa = [obj["age"]];
    var bb = [obj["name"]];

測試

這裡寫圖片描述


創建類

方式①

使用function來模擬創建類,function充當了構造函數


        //測試函數
        function test() {

            var teacher = new Teacher();

        }

        //使用function來模擬類
        function Teacher() {

        }

測試

這裡寫圖片描述


方式②

上面的function來模擬類很容易和函數混淆。

我們一般這樣做:用一個變數記住一個匿名的function當做是類,function充當了構造函數


        function test() {

            var teacher = new Teacher();
            
        }
        var Teacher = function () {


        };

測試

這裡寫圖片描述


方式③

使用JSON語法來創建類,也就是對象直接量定義方法



        var obj = {
            age: 20,
            str: "zhongfucheng",
            method:function () {
                alert("aaa");
            }

        };

測試

這裡寫圖片描述


公有屬性和方法

我們創建公有屬性應該在類中指定,創建公有方法應該使用原型對象prototype

prototype定義的屬性就類似於Java的靜態成員:在原型對象上定義了屬性,擁有這個原型對象的function所創建的對象也擁有定義的屬性!所以,我們方法中就使用prototype


        var obj = function Teacher(name) {
            this.name = name;
            if( typeof obj._init=="undefined") {
                obj.prototype.setName = function (name) {
                    this.name = name;
                };

                obj.prototype.getName = function () {
                    alert(this.name);
                };
            }

            obj._init = true;
        };

創建兩個不同的Teacher對象,name屬性是不一樣的。而它們共用同一份setName()和getName()方法

這裡寫圖片描述

值得註意的是:prototype定義的屬性只可讀的。如果你想要使用具體對象寫prototype的屬性,實際上並不是寫,而是重新為該類定義了一個同名(和prototype同名)的屬性。在讀取同名屬性的時候,優先讀取對象上的屬性,而不是prototype的。


私有屬性

我們在Java中,定義私有屬性是通過關鍵字private來修飾的。。

在JavaScript中是沒有這樣的關鍵字的,我們需要這樣做:定義在方法內【也就是function內部,也可以看作成構造函數】的變數,就是私有變數。


        var obj = function Teacher(name) {

            //這是私有屬性,外界不能訪問
            var age = 23;

            //這是公有屬性,外界可以訪問
            this.name = name;
            
            //想要訪問私有變數age,只能在這裡編寫方法來訪問。其餘的地方都不行!

            //我們通常就是在這裡編寫公有方法來訪問私有屬性

        };

靜態屬性和方法

在JavaScript中定義靜態屬性其實就是通過prototype原型對象來定義的

定義靜態的時機:

  • 當類的某個值與對象無關期望所有位置看到的結果是一樣的時候,就可以定義為類靜態屬性
  • 如果類的一個方法做的是和具體對象無關的操作,而是做一些工作操作的時候,就可以將這個方法定義為靜態的類方法
    //靜態屬性TYPE
    Book.TYPE = “IT”;

    Book.print = function(){alert(Book.TYPE);}

JavaScript中的for in迴圈

在學習AJAX的時候,發現JavaScript中for in迴圈,這種迴圈對於遍歷JSON是很好用的。於是寫下了這篇博文

for in迴圈本質上是forEach迴圈,它主要有兩個作用

  • 遍曆數組
  • 遍歷JavaScript對象

遍曆數組

當使用for in來遍曆數組的時候,它的迴圈計數器是數組元素的索引值


    var a = ['a', 'b', 'c'];
    for(var index in a) {
        alert(index);
    }

效果:

這裡寫圖片描述

遍歷JavaScript對象

當使用for in來遍歷對象的時候,它的迴圈計數器是對象的屬性名


    //對象json上,包含了兩個對象a和b屬性
    var json = {a:{num:1},b:{num:2}};

    for(var name in  json){
        alert(name);
    }

效果

這裡寫圖片描述


JS打氣球游戲

在B站中看見了一個JS大氣球這麼一個教程,才知道原來JS+HTML5+CSS3能那麼有趣。但是視頻中沒並沒有給出源碼。於是在別人的博客中搜到了對應的源碼以及他自己實現的思路,該博主對其進行了改編。

http://www.cnblogs.com/morang/p/7636148.html

以上的博文有源碼的下載。下麵我就直接貼上源碼了。思路就在博文中。


<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html>
    <head>
        <title>氣球大戰</title>
        <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0">
        <style>

        /*CSS3能夠將氣球描繪出來,使用到了圓形、旋轉、陰影等技術*/
            body{margin:0px;padding:0px;}
            #ballDiv{position: fixed;top: 0;left: 0;}
            .balloon{
                width:150px;
                height:150px;
                position:absolute;
                left:0px;
                top:0px;
                background-color:#f3778d;
                border-radius:50% 50% 10% 50%;
                transform:rotate(45deg);
                box-shadow:1px 1px 20px 20px pink inset;
                z-index:10;
            }
            /*這裡使用到了偽元素,可以不用到html中定義元素就可以實現功能了!*/
            .balloon:after{
                width:20px;
                height:20px;
                content:"";
                display:block;
                background:transparent;
                position:absolute;
                right: -15px;
                bottom: -15px;
                border-left:5px solid pink;
                border-top:5px solid pink;
            }
            /*這裡使用到了偽元素,可以不用到html中定義元素就可以實現功能了!*/
            .balloon:before{
                    width: 2px;
                    height: 50px;
                    content: "";
                    display: block;
                    background: #ffc0cb;
                    position: absolute;
                    right: -10px;
                    top: 100%;
                    margin-top: -16px;
                    transform: rotate(-45deg);
            }
        </style>
    </head>
    <body>
        <div id="gameinfo" style="transform: translateZ(360px);">
            <p>
                最高連擊:<span id='maxDoubleHit'>0</span>               
            </p>
            <p>
                本次游戲:<span id='currentDoubleHit'>0</span>               
            </p>
            <p id="gamemsg" style="display:none;">
                <span style="color:red;font-weight:bold;">
                    Game Over
                </span>
                <button onclick="javscript:location.reload();">
                    重新開始
                </button>
            </p>
        </div>
        <div id="ballDiv">
            
            
        </div>
        <!--<div class="balloon"></div>-->
        <script>
            var maxDoubleHit=localStorage.getItem('eliminateCount')||0
            var currentDoubleHit=0
            //當做一個緩存池,優化性能的。
            var bnElements=[];//存放所有氣球
            var random=Math.random;//隨機函數
            var wW=window.innerWidth;//視窗寬度
            var wH=window.innerHeight;//視窗高度
            var ballW=160;//氣球的寬度
            var ballH=300;//氣球的寬度
            var minSpeed=3;//最小速度,每次向上移動至少3px
            var speedNum=5;//速度的定量
            var defBnNumber=5;//初始化氣球
            var moveTimer;
            var isEnd=false;            
            var jindex=1;
            var ballDiv=document.getElementById('ballDiv');
            
            //初始化           
            init(defBnNumber);
            //移動
            move();
            //綁定單擊事件
            bindClick();
            
            //游戲信息
            document.getElementById('maxDoubleHit').innerText=maxDoubleHit
            function record(){
                if(isEnd){
                    clearTimeout(moveTimer);
                    bnElements=[];
                    document.getElementById('gamemsg').style.display='block';
                    document.getElementById('gameinfo').style='transform: translateZ(360px);position: fixed;top:0;left:0;z-index:999';
                }
                else{
                    init(1);
                    document.getElementById('currentDoubleHit').innerText=++currentDoubleHit;
                    if(currentDoubleHit>maxDoubleHit){
                        document.getElementById('maxDoubleHit').innerText=currentDoubleHit;
                        localStorage.setItem('eliminateCount',currentDoubleHit)
                    }
                }
            }
            //初始化氣球
            function init(num){
                //創建一個虛擬文檔節點
                var docFragment=document.createDocumentFragment();
                for(var i=0;i<num;i++){
                    var bnElement=document.createElement('div');
                    bnElement.className='balloon';
                    //速度隨機,限定最小值
                    var speed=Math.max(minSpeed,~~(random()*speedNum));
                    bnElement.setAttribute('speed',speed);//~~取整 移動速度
                    bnElement.setAttribute('id','ball-'+jindex++);
                    //分散排列
                    var x=(~~(random()*wW))-ballW;
                    x=Math.max(0,x);
                    bnElement.style.left=x+'px';                
                    bnElement.style.top=wH+'px';//露一點出來         
                    
                    //1.先將創建的氣球放入創建的虛擬文檔節點
                    docFragment.appendChild(bnElement);
                    bnElements.push(bnElement);
                }
                //2.將虛擬文檔節點添加到body中
                ballDiv.appendChild(docFragment);
            }

            //使用定時器來對氣球進行移動。
            function move(){
                var bl=bnElements.length
                for(var i=0;i<bl;i++){
                        var currentElement=bnElements[i]
                        if(currentElement==null){
                            continue;
                        }
                        var offsetTop=currentElement.offsetTop;
                    if(offsetTop>0){//視窗中

                            //offset就是針對視窗的位置來進行移動的。
                            var speed=currentElement.getAttribute('speed');
                            currentElement.style.top=offsetTop-speed+'px'
                        }
                        else{
                            //移除dom節點
                            //ballDiv.removeChild(currentElement);
                            //移除數組中
                            //bnElements.splice(i,1);
                            //init(1);
                            isEnd=true;
                            record();
                        }
                }
                moveTimer=setTimeout(move,1000/30);
            }

            //對所有的氣球進行單擊監聽事件,不要單獨為每個氣球來進行監聽,這樣耗費性能!
            function bindClick(){
            
                ballDiv.addEventListener('click',clickFunc,false);
                function clickFunc(e){
                    if(!isEnd && e.target.className=='balloon'){
                        bnElements.splice(bnElements.lastIndexOf(e.target),1);

                        //這裡使用call主動調用,在boom方法中我們就可以使用this指針了。
                        boom.call(e.target,function(){
                            e.target.parentNode.removeChild(e.target);
                            record();
                        });
                    }
                }
            }
            function boom(callback){
                //var that=this; //替換了上下文,但是沒有使用this的意義.
                var speed=this.getAttribute('speed');
                this.timer=setInterval(function(){
                    this.style.opacity=0.1*(speed--)
                    if(speed<1){
                        callback&&callback();
                        clearInterval(this.timer);
                    }
                }.bind(this),30);
            }
            
        </script>
    </body>
</html>

看了視頻也學到了之前一直沒有註意的東西:

  • CSS3很厲害啊,能將方形的div轉成是橢圓形的[也就是氣球的形狀],還有盒子的陰影設置。
  • 使用偽元素就可以不用直接在html中設置標簽了。配合CSS3也能夠做出對應的樣式。
  • 使用實體邊框配合CSS3也可以做出不同的形狀樣式
  • 在生成元素的時候,可以先將要生成的元素加入到文檔片段中,再使用文檔片段來進行一次性添加到body上,這樣性能會好很多!
  • 使用~~運算符能夠取整數
  • 限定氣球的邊界就可以使用max和min函數來進行限定。這也是很好用的。
  • 移動氣球我們需要用到定時器。

  • 使用call主動調用方法,把目標對象傳遞過去的話,我們就可以使用this指針了。
  • 在定時器中使用bind(this),就可以在定時器中使用this指針的,因為定時器預設是由瀏覽器window來進行調用的,預設是不能使用this的
  • 綁定單擊事件的時候,不要使用迴圈來進行綁定,這樣太耗費性能了,我們可以使用監聽事件來進行一次綁定。
  • 在遍歷元素數組的時候,條件是元素數組的長度時,我們可以先把該元素數組的長度初始化出來,那麼也可以提升性能!不然就每次判斷前都要去查詢數據的長度!

for(var i=0,len = array.length; i<len;i++){}

如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同學,可以關註微信公眾號:Java3y


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言: 考慮自己網站的圖片展示,而且要支持移動端和PC端。自己寫的代碼也不盡如意,要寫好的話也需要時間,於是就想到了使用相關插件。 準備: PhotoSwipe 官網地址:http://photoswipe.com/ 英語還可以的同學可以看官方文檔學習:http://photoswipe.com/d ...
  • 數據流向 數據的改變發生通常是通過用戶交互行為或者瀏覽器行為(如路由跳轉等)觸發的,當此類行為會改變數據的時候可以通過 dispatch 發起一個 action,如果是同步行為會直接通過 Reducers 改變 State ,如果是非同步行為(副作用)會先觸發 Effects 然後流向 Reducer ...
  • [1]打包公共代碼 [2]動態導入 [3]懶載入 [4]剔除無用代碼 [5]長緩存優化 [6]公用代碼內聯 ...
  • 請點擊相應的步驟查看詳情 我們首先搭建一個 dva Demo 項目(請參考react快速構建一個應用項目),然後逐步完成以下內容: 第一步,我們會劃分一下整體的項目結構,熟悉每一部分是什麼概念;接下來我們會說如何抽離 model,以及 model 設計的一些思路;然後我們會根據項目的情況說明如何合理 ...
  • Paradise_追逐者的es6(二) 1.es6三種聲明方式 2.變數的解構賦值 3.擴展運算符和rest運算符 ...
  • 第一階段: HTML+CSS: HTML進階、CSS進階、div+css佈局、HTML+css整站開發、 JavaScript基礎: Js基礎教程、js內置對象常用方法、常見DOM樹操作大全、ECMAscript、DOM、BOM、定時器和焦點圖。 JS基本特效: 常見特效、例如:tab、導航、整頁滾 ...
  • 前言 最近在通過教學視頻學習angularjs,其中有gulp的教學部分,對其的介紹為可以對文件進行合併,壓縮,格式化,監聽,測試,檢查等操作時,看到前三種功能我的心理思想是,網上有很多線上壓縮,線上解壓,css格式化,js格式化類似的工具,為什麼還需要學習一項新技術呢。當學完了之後,被自己見識短淺 ...
  • 定寬高。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...