JavaScript高級(01)

来源:http://www.cnblogs.com/lilong329329/archive/2017/10/07/7634363.html
-Advertisement-
Play Games

前端開發工具 1.1、 WebStorm介紹和下載 l 介紹 WebStorm是JetBrains 推出的一款強大的HTML5編輯工具,擁有豐富的代碼快速編輯,可以智能的補全代碼、代碼格式化、html提示以及代碼檢查和快速修複等,支持不同瀏覽器的提示,同時也是一款JavaScript 開發工具,擁有 ...


 前端開發工具

1.1、 WebStorm介紹和下載

l  介紹

WebStorm是JetBrains 推出的一款強大的HTML5編輯工具,擁有豐富的代碼快速編輯,可以智能的補全代碼、代碼格式化、html提示以及代碼檢查和快速修複等,支持不同瀏覽器的提示,同時也是一款JavaScript 開發工具,擁有即時編輯(chrome)、自動完成、debugger、Zen Coding、HTML5 支持、JSLint、Less支持、CoffeeScript支持、Node.JS、單元測試、集成git和svn版本控制等特性,推薦前端工程師使用。

WebStorm被廣大中國JS開發者譽為“Web前端開發神器”

 

l  官網:http://www.jetbrains.com/webstorm/

 

 

js的基礎回顧

// 1、JS中數據類型有哪些?

// JS中有6種數據類型,其中五種基本數據類型(Number,Boolean,String,Undefined,Null)和一種複合數據類型(Object)

console.log('--------------------JS中數據類型有哪些END------------------------');

 

// 2、如何判斷變數數據的類型?

// 使用typeof來判斷變數的數據類型

var i = 12; // 'number'

var s = 'abc'; // 'string'

var b = true; // 'boolean'

var u = undefined; // undefined

var oDate = new Date(); // 'object'

var arr = [12,5]; // 'object'

var o = {}; // 'object'

var fn = function(){alert('xxx')}; // 'function'

var n = null; // 'object'

console.log(typeof i);

console.log(typeof s);

console.log(typeof b);

console.log(typeof u);

console.log(typeof oDate);

console.log(typeof arr);

console.log(typeof o);

console.log(typeof fn);

console.log(typeof n);

// 註意點:

 

// 1. JS解釋器認為null是object數據類型的一種特殊形式,而null在JS裡面特指空對象

// 2. function(){}的數據類型是function, 也就是說function也是一種基本數據類型,而不是對象的一種特殊形式。實際上在JS中,函數是一個極為容易引起誤解或者引發歧義的數據類型,它可以是獨立的數據類型,也可以被稱為類或者構造函數,還可以作為函數對象等。

console.log('--------------------如何判斷變數數據的類型END------------------------');

 

// 3、JS中的空類型有哪些?

// 1).null 是一個原始的數據類型,只有一個值null, 特指空對象

// 2).undefined是一個原始的數據類型,只有一個值undefined

// 1、定義變數沒有賦值,此時變數的值是undefined

var a;

console.log(a);// undefined

///2、函數沒有返回值或者沒有返回具體的值都是預設返回undefined

function show() {

    console.log('我沒有返回值,預設返回undefined');

}

console.log(show()); // undefined

///3、訪問對象中一個不存在的屬性

console.log(window.abc); // undefined

console.log('--------------------JS中的空類型有哪些END------------------------');

 

// 4、JS中代表哪些數據代表false?

// 數字0、空字元串''、false、空對象null、NaN、undefined

 

// 5、JS中 === 和 == 有什麼區別?

// ==  用來比較兩個變數的值是否相等,先做數據類型的轉換,在做比較

// === 全等,嚴格的比較,先比較數據類型,數據類型不相等,就立刻返回false

console.log('1' == 1); // true

console.log('1' === 1); // false

console.log('--------------------JS中 === 和 == 有什麼區別END------------------------');

// 6、JS中的in運算符有什麼用?

// 1). 用來迴圈數組,性能低,建議使用普通的for

var arr = [12,5,8];

for (var i in arr) {

    console.log(i + '---' + arr[i]); // 0-12 1-5 2-8

}

// 2). 用來迴圈對象

var p = {

    name: 'Jack',

    age: 20,

    gender: 'male'

};

for (var name in p) {

    console.log(name + '---' + p[name]); // 'name---Jack' age---20 'gender---male'

}

// 屬性操作:

//   i).  點 . 比較方面,不能接收變數

//  ii).  中括弧 [] 可以接收變數,可以替代所有點出現的位置

// 3). 用來判斷某個屬性是否屬於某一個對象

console.log('name' in p); // true

console.log('abc' in p); // false

console.log('--------------------JS中的in運算符有什麼用END------------------------');

// 7、JS中的邏輯中斷?

// 且&&  或 ||

// && 當左側為false,直接返回左側的結果;當左側結果為true,返回右側結果

// || 當左側為true,直接返回左側結果; 當左側結果為false,返回右側結果

console.log(1 || 2); // 1

console.log(0 || 2); // 2

console.log(null || 0);  // 0

面向對象的介紹:那麼什麼是對象呢?這裡只需要舉出相關例子就是可以不需要準確說出概念

面向過程:完成一件事情的所有步驟都親力親為,一步一步來完成。例如要吃餃子,就必須自己剁餡兒、和麵、擀餃子皮兒、包餃子

         面向對象:完成一件事情,直接去找能做這件事的人。例如吃餃子,直接找老婆(如果沒有就去餃子館吧)

 

         面向過程:是事件的執行者

         面向對象:是指揮者

 

         一言以蔽之:面向對象就是對面向過程的封裝!

 

那麼為什麼要面向對象呢?

1)  提高代碼的復用性,簡化開發

2)  使代碼結構清晰

3)  在JS中有一個特殊的作用:防止代碼污染

那麼什麼是代碼污染呢?代碼污染其實就是代碼中含有重覆的變數並且其中後面的代碼吧前面的代碼給覆蓋了,就是再調用的時候不知道找不到自己真實的需要調用的那個對象或者是方法

如何解決代碼污染?

1、我們可以把定義的方法放在對象中裡面,然後使用對象調用自己的方法基本上可以防止代碼污染如下:

創建對象的兩種方式:

第一種就是使用對象的直接量的方式:

在定義對象的時候,直接使用JSON格式來定義一個JS對象,並且為這個對象賦值屬性和方法,稱為對象的直接量(字面量)

 

這種方式創建的對象,預設是Object類型的對象(這種方式創建object對象)

 

l  案例代碼:(也就是使用json格式的數據來定義對象稱作為對象的直接量)(也就是使用json格式的數據來定義對象實現這個過程)

 

效果如下:

l  缺陷:

u  只能使用1次,無法重覆利用,每次都要編寫相同代碼創建新對象

l  使用場景:

u  對象只需要一次使用的時候。比如作為傳遞參數;

u  自己封裝JS框架(函數)的時候。

第二種方式就是使用構造函數創建對象

l  構造函數創建對象的一般步驟:

1)  通過function指定一個構造函數,與普通函數沒差別,只是約定首字母大寫以區分

2)  然後在構造函數中通過this.屬性名=屬性值來完成對象屬性初始化。

3)  最後通過new關鍵字創建對象(實例)

 

其中的代碼案例:

效果如下:

 

 

 那麼對象中的函數相同嗎?

測試:

結果顯示:

實際上查看記憶體中對象的屬性發現p1和p2中各有一份 sayHello 方法:

結論:

         通過上面的實驗我們發現,對象中的所有屬性,包括定義的方法,都是每個對象獨有的,不會共用。

    屬性不共用可以理解,但是方法都是一樣的,如果也不共用,那麼就是對記憶體的極大浪費。

 

 

l  優勢:

u  對象可以重覆創建

l  缺點:

u  對象中相同的方法,無法實現共用,記憶體占用高

 

 

由上面可以引出來對象原型的概念

對象原型(prototype)

在JS中,每一個構造函數都會有一個prototype(也是一個對象)屬性,任何由同一個構造函數創建的對象,都會共用這個prototype對象,並且可以具備這個prototype的所有屬性(成員)

原型的基本的使用方法

剛開始的時候沒有設置對象原型的時候,定義一個空的構造函數,只給出name屬性,當列印age屬性的時候結果是undefined,因為沒有給屬性

 

 

 

結果:

                  列印控制臺中是undefined的。

         查看對象屬性也是只有name屬性,沒有age:

當使用原型給構造函數添加新的屬性的時候,也就是使用prototype給構造函數添加新的屬性

 

此時控制臺上已經顯示了屬性

這個時候再次查看對象的屬性:

發現p1和p2對象中雖然依然沒有age,但是構造函數Person的prototype中已經有age了,又因為對象會共用prototype的成員,所以每個對象都可以使用age屬性了!

 

 

例外一種情況進行總結:

1.1.1.1、 給對象從原型中繼承的屬性賦值

嘗試修改對象中,繼承自prototype的屬性值age:

結果:p1的age已經變為30, p2沒變

 

 那麼問題來了:

問題,既然是共用的屬性,那麼為什麼p1修改了,p2值沒變?

查看記憶體中的狀態:

我們發現:prototype中的age沒有改變,而是在對象p1中新增了自己的age屬性,並且賦值為30

 

結論:當原型和對象自身都有相同屬性時,對象中的屬性優先!

 

1.1.1.1、 總結

1)  當我們訪問對象中的屬性時,預設會先在當前對象中查找;如果在當前對象找不到,就會去對象的prototype中查找

a)         事實上,prototype也是對象,因此在prototype對象中找不到,會到prototype對象的prototype中找,逐級向上形成“原型鏈”,原型鏈的最頂級的是Object.prototype

b)        那麼Object.prototype也是對象,再向上還有嗎?沒有了,再向上是null。Object.prototype就是原型鏈的根

2)  修改對象的屬性,不會修改prototype中的屬性,而是在對象中創建新的屬性

3)  某些瀏覽器支持__proto__屬性,與prototype是同一個東西,但是某些瀏覽器還不支持。所以一般不要用

 

 

 

再有一種情況就是通過原型來更改構造函數

為了減少對象記憶體占用,我們一般創建構造函數的時候,會把經常變化的屬性在構造函數中聲明,每個對象都有自己的屬性。然後把公用的不變化的東西(通常是函數)通過原型來添加。

此時的驗證結果顯示:

每個對象都可以調用sayHello方法,證明共用了方法。 各個對象的sayHello方法判斷是相等的。證明記憶體中只有一份。

 

總結構造函數創建對象的方法:

1、  構造函數裡面寫變化屬性

2、  原型上去添加方法

通過原型擴展js的原生對象

事實上不僅僅我們自己定義的對象有原型,JS中原生的對象也有原型。我們可以通過原生對象的原型對原生的JS進行擴展!

 

 

原生的JS中,Array對象並沒有sum方法,嘗試調用報錯:

 

 

我們使用原型進行擴展:

結果顯示:

疑問?

擴展字元串的trim方法

 

 

 

終極總結:判斷一個 對象的類型

那麼如何判斷一個對象的類型呢?

         1)instance of

         2)通過類的位元組碼Class對象

 

方式一:instanceof作用是用來判斷一個對象是否屬於一個類

案例代碼:

結果顯示:

 

 由此得出的總結結論:instanceof 可以基本準確的判斷對象的所屬類型,但是當 instanceof後面跟的是類型是父類類型的時候,判斷是不准確的。這一點與Java類似

 

如果要是更準確的來判斷對象類型的話,是可以通過類的位元組碼對象,也就是和java中的反射技術是差不多的,但是js中是沒有類的概念的,更不要說class對象,但是js中類似的概念是構造函數constructor

 

也就是所說的方式2   :作用constructor用來檢測直接的構造者

通過constructor來準確判斷對象類型

結果顯示的也是返回的是布爾值

 

  

 

 

this關鍵字的總結介紹:

                                    

在Java中,this關鍵字表示的是當前對象。比如在方法中使用,就是調用方法的對象。

 

在JavaScript中,this也是類似的。只不過JS中方法無需定義在類中,所以很多人對this的含義就懵逼了。

 

 

代碼案例的實現:

<!DOCTYPE html>

<html>

    <head>

       <meta charset="UTF-8">

       <title>this關鍵字的含義</title>

    </head>

    <body>

       <script>

           // 演示: this關鍵字的含義

           // this指的是當前的方法屬於誰,只看調用,誰調用就指向誰,所以我們只需要搞清楚調用方法的對象即可

           // 1. 全局函數中的this

           function show() {

              console.log('全局函數中的this:' + this);

           }

           // 全局函數 預設是註冊到window對象上中

           // 而調用window中的任何成員,預設是可以省略window.的

           // 這裡的show()完整的寫法其實是:window.show(); 因此肯定當前的方法屬於window這個對象

           // show(); // Object window

           window.show();

 

           // 2. 對象中的this

           var p = {

              name: 'Jack',

              age: 20,

              gender: 'male',

              sayHello: function() {

                  console.log('Hello, I am' + this.name + ',' + this.age + 'years old');

              }

           };

           // 對象中的this,指向的是調用該方法的對象,現在該方法屬於p這個對象,因此this指向了p

           p.sayHello(); // 'Hello, I amJack,20years old'

 

           // 3. 事件函數中的this

           // 當前的事件註冊到了document對象身上

           // 事件觸發時,調用該事件處理函數的對象就是事件源對象,也就是document對象,此時事件函數裡面的this指向了事件源對象

           document.onclick = function() {

              console.log('事件函數中的this:' + this); //object HTMLDocument

           };

 

           // 4. 定時器裡面的this

           // setTimeout方法本身就是window對象的一個方法,那麼時間到了以後,

           // 定時器裡面的函數有誰來調用? window, 所以定時器裡面的this就是window

           setTimeout(function() {

              console.log('定時器裡面的this:' + this); // object Window

           }, 1000);

       </script>

    </body>

</html>

 

關於this關鍵字進行總結:

1)  其實記住一點就夠了:this指的是當前的方法屬於誰,只看調用,誰調用就指向誰

2)  對象外的全局函數,this是window

3)  對象中的方法,被對象調用時,this是對象自己

4)  事件處理函數,this是事件綁定的對象

5)  定時任務函數,this是window

 

 

3.8 、對象的繼承(組合式繼承、構造函數繼承、原型繼承)

 

3.8.1  組合式繼承:組合式繼承就是把 一個對象的屬性 全部加到另一個對象中。也被稱為屬性拷貝。

應用:組合式繼承主要用在 對象的直接量 繼承另一個 對象的直接量時。

案例:

結果顯示:

使用的場景:比如我用對象封裝了一個框架,現在要對該框架的方法進行擴展,新增更多方法。此時就可以把新增的方法定義到新的對象中,使用組合式繼承來完成 方法的擴展。

//比如可以通過一個匿名對象,給o1可以擴展更多的方法

結果顯示

3.8.2  構造函數繼承

如果對象不是 直接量對象,而是通過構造函數new出來的,那麼如何繼承另一個構造函數中的屬性呢?

結果顯示:

 

 

我們發現直接在子類的構造函數中直接調用父類的構造函數不能實現屬性的繼承,因為直接調用父類的構造函數,此時父類的構造函數屬於全局函數,所以裡面的this指向了window對象,不是Worker的實例,這個時候我們要去改變父類構造函數裡面this的指向,讓父類構造函數裡面的this指向Worker的實例

 

函數也是對象,任何函數都可以調用兩個方法:call和apply ,來自於Function的原型

call和apply都會導致調用的函數被執行,但是可以在執行時指定this

名稱

用法

參數說明

call

fn.call(fn函數裡面this的值,參數1,參數2..);

第一個參數是被調用函數裡面this的值,真實的參數從第二個開始

apply

fn.apply(fn函數裡面this的值, [參數1,參數2..]);

同上,實際參數是數組結構

 

結果顯示:

我們發現,worker具備了父類中的所有屬性,但是,Person類在原型中擴展的方法 sayHello 並沒有被繼承。訪問時報錯

並且,在執行instanceof的時候,無法判斷worker屬於Person類的實例

 

特點:

1)  可以繼承父類構造函數中定義的屬性

2)  父類原型中定義的方法無法訪問,擴展性差     

3)  instanceof 判斷失效,因為子類原型與父類原型沒有關聯

 

3.8.3   使用的是原型繼承;

為瞭解決上面的問題我們可以使用的就是原型繼承的方式進行實現這個過程:

 

 

 總結(非常重要可以查看)

JS的繼承步驟:

1)  在你的構造函數中,調用父類的構造,但是要用call或apply

2)  讓你的構造函數的prototype指向父類的對象

3)  因為原型被覆蓋,因此原型中的constructor也被覆蓋,需要修正constructor指向子類的構造函數

 

註意:原型繼承,其實是讓子類原型指向了父類對象。 這樣父類對象就 覆蓋了子類prototype中的所有屬性。其中constructor屬性也被覆蓋成了父類的。因此,在使用原型繼承時,必須手動把子類的原型中的constructor屬性修改為子類的構造函數!

 


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

-Advertisement-
Play Games
更多相關文章
  • Card Collector HDU - 4336 ans[S]表示獲得S的卡片次數的期望考慮到達S前一次的卡片1.獲得一張已獲得的 期望是ans[S]*sum{p[i]|i在S中}2.獲得一張未獲得的 期望是sum{ans[S-i]*p[i]|i在S中}3.未獲得卡片 期望是ans[S]*p[0] ...
  • 過濾器 字面義上理解的過濾器類似下圖,從一堆物品中篩選出符合條件的留下,不符合的丟棄。 GOF 職責鏈 GOF中有一種設計模式叫職責鏈,或者叫責任鏈,常規的UML圖如下: 正統的職責鏈是將一個請求發給第一個接收者,接收者判斷是否屬於自己能處理的,如果能處理則執行操作並中止請求下發,流程到此為止。如果 ...
  • 設計模式的最終目的是解決軟體的高可維護性和高復用性問題以及應對大數據、高併發、高智能的挑戰。 設計模式遵循的原則: 1 開閉原則。對開展開放,對修改關閉。不修改原代碼的前提下實施功能擴展。 2 里氏代換。子類可以代替基類出現在任何地方。 3 依賴倒轉。依賴於抽象,不要依賴於實現。代碼往上走,數據往下 ...
  • (2.2)第二種擴展方式,隱示擴展,通過__proto__屬性。 2,簡單方式實現繼承 使用圖梳理一下原理: 索引的變化: (1) ...
  • 編寫高效率的js,第一步就是將自己的代碼風格規範起來,畢竟寫一堆爛代碼,是一件讓自己很難容忍的事情。我就是這樣,業精於勤荒於嬉,行成於思毀於隨,對代碼編寫提出高標準,對團隊,對個人都是一件應該努力的方向。 進入正題,2017年10月起,我會每周優先更新兩個重要部分,以下藍色字體代表已更新的內容,黑色 ...
  • 前 言 MUI是一款最接近原生APP體驗的高性能前端框架,它的比較重要的功能是:下拉刷新、側滑導航、滑動觸發操作菜單和頂部(底部)選項卡等 最近用MUI做手機app應用的時候,遇到的小bug。順便研究了一下這個tab-top-webview-main,這裡給大家分享一下。 1主頁代碼 2子頁代碼 3 ...
  • jquery ajax調用webservice(C#)要註意的幾個事項: 1、web.config里需要配置2個地方 <httpHandlers> <remove verb="*" path="*.asmx"/> <add verb="*" path="*.asmx" validate="false ...
  • 原文鏈接:http://www.zhangxinxu.com/wordpress/?p=466 以上代碼在IE10中測試與張老師文章中的效果有些出入,希望在以後的工作學習中引起註意,並且進行深度研究哈哈~ ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...