<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] # 對象 ## 概念 &emsp;&emsp;JavaScript的對象是無序屬性的集合。其屬性可以包含基本值,對象或者函數。可以包含基本類型值和復雜類型值。js中對象就是一組鍵值對 &emsp;&emsp;對象是一種復合值,它將很多值(原始值或其他對象)聚合在一起,可通過屬性名訪問這些值。。而屬性名可以是包含空字符串在內的任意字符串。 &emsp;&emsp;JavaScript中的對象是現實生活中對象的抽象。即顯示生活中的對象使用JavaScript來描述。 * 事物的特征在對象中用**屬性**來表示。 * 事物的行為在對象中用**方法**來表示。 <br> JavaScript對象也可以稱作一種數據結構。 <br> ## **屬性和方法** 1. 如果一個變量屬于一個對象所有,那么該變量就可以稱之為該對象的一個屬性,屬性一般是名詞,用來描述對象的特征。 2. 如果一個函數屬于一個對象所有,那么該函數就可以稱之為該對象的一個方法,方法是動詞,描述對象的行為和功能。 3. 屬性和方法統稱為對象的成員(成員變量) ## **創建對象** 創建對象有四種方式 <br> ### **一、通過字面量創建對象** &emsp;&emsp;對象也可以用字面量方式表示,而且也可以對象的字面量值賦值給一個變量,此時這個變量就代表這個對象。 &emsp;&emsp;使用字面量方式表示對象,又叫創建字面量對象,如下: ``` var person = { name: '馮寶寶', age: 18 }; ``` <br> #### **語法格式** >[success]var 對象名 = {鍵:值, 鍵:值...} ; &emsp;&emsp;語法格式分析 1. 對象名 -> 本質是變量名; 2. {} -> 固定格式,表示封裝一段代碼,類似于函數的大括號; 3. 鍵:值 -> 鍵-值對,固定格式; &emsp;&emsp;鍵 -> 表示 屬性名,類似于變量名; &emsp;&emsp;值 -> 表示 屬性值,類似于變量值,可以是基本數據類型(String,Number...)或引用數據類型(數組,對象); 6. 鍵 和 值之間使用 ":" 隔開,鍵值對和鍵值對之間用 "," 隔開; 注意:對象名類似于變量名,鍵也類似于變量名,對象中存在鍵,好比變量中存在變量。 &emsp;&emsp;根據以上語法格式就可以創建對象了。我們知道,JavaScript對象是由屬性和方法組成的,所以只要確定了一個對象的屬性和方法,就可以使用代碼創建出這個對象了。 <br> **例:** 1、創建一個 "人" 對象 屬性:name(馮寶寶),age(18),gender(true) 方法:sayHi(打招呼-瓜娃子) ``` var person = { name: '馮寶寶', age: 18, gender: true, sayHi: function () { console.log('你好,瓜娃子,我叫 '+this.name); } }; ``` <br> ### **二、 通過Object構造函數創建對象(內置構造函數)** &emsp;&emsp;構造函數實質是函數,Object()是JavaScript內置的一個構造函數,可以用來創建對象 <br> #### **語法格式** >[success]var 對象名 = new 內置構造函數名(); 語法格式分析 new -> 用于調用內置構造函數的關鍵字 步驟: 1. 創建出一個空對象 ``` var obj = new Object(); console.log(obj); ``` 2. 給對象添加屬性和方法并賦值 **語法格式** >[success]對象名.屬性名 = 屬性值; 對象名.方法名 = function(){...} 區別于字面量方式的 鍵值對! { 屬性名:屬性值,方法名:function(){...} } 利用內置構造函數的方式,創建一個完整的hero對象,如下 ``` //使用new關鍵字來調用Object()構造函數,創建出一個空的對象 var obj = new Object(); console.log(obj); //動態地給對象設置屬性和方法 obj.name = '孫尚香'; obj.gender = false; obj.weapon = '弩炮'; obj.equipment = ['急速戰靴', '宗師之力', '無盡戰刃', '泣血之刃', '閃電匕首', '破曉']; obj.attack = function () { console.log(this.name + ':收割人頭'); } obj.run = function () { console.log(this.name + ':加速奔跑'); } console.log(obj.name); console.log(obj.equipment); obj.attack(); obj.run(); ``` **注意** &emsp;&emsp;創建字面量對象的方式本質上是對內置構造函數方式縮寫,字面量方式的底層也是使用new調用內置構造函數來完成的。兩者比較,內置構造函數方式比字面量的方式更靈活。 <br> ### **三、自定義構造函數** &emsp;&emsp;自定義構造函數和內置構造函數類似,自定義構造函數是由自己定義,而內置構造函數是JavaScript庫內置(已經定義好的)的。 **語法格式** ``` //定義一個構造函數,帕斯卡命名:所有單詞首字母都大寫。 function Hero(name) { //this 表示當前構造函數創建的對象 //this 用來設置對象的屬性和方法 this.name = name; } ``` **注意:** >[info]1、使用帕斯卡命名:函數名首字母都大寫,如果函數由多個單詞組成,每個單詞首字母都要大寫。 2、使用this表示當前構造函數創建的對象 3、使用this設置對象的屬性和方法 &emsp;&emsp;自定義構造函數 跟 內置構造函數 的調用方式一樣! 都是使用**new**關鍵字來調用。 ``` var hero = new Hero('孫尚香');//調用構造函數時,傳入實參 ``` &emsp;&emsp;使用自定義構造函數創建一個Hero的完整代碼如下。 ``` //定義一個構造函數,帕斯卡命名:所有單詞首字母都大寫。 function Hero(name, gender, weapon, equipment, blood) { //this 表示當前構造函數創建的對象 //this 用來設置對象的屬性和方法 this.name = name; this.gender = gender; this.weapon = weapon; this.equipment = equipment; this.blood = blood; this.attack = function () { console.log(this.name + ':收割人頭'); } this.run = function () { console.log(this.name + ':加速奔跑'); } } var hero1 = new Hero('孫尚香', false, '弩炮', ['急速戰靴', '宗師之力', '無盡戰刃', '泣血之刃', '閃電匕首', '破曉'], 100); var hero2 = new Hero('劉備', true, '劍', ['頭盔', '鎧甲'], 100); console.log(hero1, hero2); ``` >[info]**構造函數是這幾種創建對象的方式中,最靈活,最常用的一種。** <br> ### **四、工廠模式** 工廠模式是軟件工程領域一種廣為人知的設計模式,這種模式抽象了創建具體對象的過程。 工廠模式:使用創建并返回特定類型的對象的**工廠函數**(其實就是普通函數,沒啥區別,只是叫法不同),可以創建多個相似的對象。 工廠函數: &emsp;&emsp;用函數來封裝特定接口創建對象的細節。 &emsp;&emsp;把實現同一事情的相同代碼,放到一個函數中,以后如果再想實現這個功能,就不需要重新編寫這些代碼了,只要執行當前的函數即可,這就是函數的封裝,體現了**高內聚、低耦合**的思想:減少頁面的中的冗余代碼,提高代碼的重復利用率。 ``` ~~~ //在函數內創建一個對象,給對象賦予屬性及方法再將對象返回即可。 function createPerson(name) { var o = new Object(); o.name = name; o.sayName = function () { alert(this.name); }; return o; } var obj = createPerson("張三");//將'張三'作為實參調用函數,此時對象o的name屬性的值為張三。 var obj2 = createPerson("李四"); alert(obj instanceof Object); alert(obj instanceof createPerson) ~~~ ``` <br> ### 各種創建函數的方法的優劣 >[info] > >**1、字面量方式** &emsp;&emsp;優點:方便快捷,即寫即用 &emsp;&emsp;缺點:每個對象都要寫一堆代碼 >**2、內置構造函數方式** &emsp;&emsp;優點:沒什么優點 &emsp;&emsp;缺點:每個對象都要寫一堆代碼 >**3、自定義構造函數** &emsp;&emsp;優點:較前三種方式靈活,函數只需創建一次,可重復使用,提高開發效率;能確定當前被創建的對象的類型。 &emsp;&emsp;缺點:如果對象只使用一次,要比字面量方式多些幾行代碼 >**4、工廠函數** &emsp;&emsp;優點:大量創建相似對象時,可以節省大量代碼。 &emsp;&emsp;缺點:不能確定不能確定對象類型 <br> ## 對象的訪問 **訪問對象的成員** 訪問屬性的格式: &emsp;&emsp;對象名.屬性名;(點語法) dog.name;或dog['name'];(中括號語法) 訪問方法的格式: &emsp;&emsp;對象名.方法名(); dog.bark(); 或 dog.['bark'] (同上,有點語法和中括號語法) ``` var dog = { name: '花卷', age: 2, gender: true, bark: function () { console.log(this.name + ':汪~汪'); } } console.log(dog.name);// 訪問屬性,又叫調用屬性 dog.bark();// 調用方法 ``` 函數和方法的區別,從定義和調用的角度來看 >[info]1、定義 函數:獨立存在 方法:依賴于對象存在,語法跟匿名函數語法相似 2、調用 函數:函數名(); 方法:對象名.方法名(); <br> ## **new關鍵字和this關鍵字詳解** <br> ### **new關鍵字** 構造函數 ,是一種特殊的函數。它總是與new關鍵字一起使用,完成對象的創建。 **舉例:** ~~~ // 定義構造函數 function Person(name, age, gender) { ? ?// 1、在內存中創建一個新的空對象; ? ?// var obj = new Object(); ? ?// 2、將this指向創建出來的新對象 ? ?// this = obj; ? ? ?// 3、執行構造函數的代碼(設置屬性和方法) ? ?// 添加屬性 ? ?this.name = name; ? ?this.age = age; ? ?this.gender = gender; ? ? ?// 添加方法 ? ?this.sayHi = function () { ? ? ? ?console.log('你好,瓜娃子~,我是' + this.name); ? } ? ?// 4、返回這個新對象; ? ?// return this; } var per = new Person('馮寶寶', 18, true); console.log(per); ~~~ new在調用構造函數中所執行的步驟 >[info]1. 在內存中創建一個新的空對象; var obj = new Object(); >2. 將this指向創建出來的新對象; this = obj; >3. 執行構造函數的代碼(設置屬性和方法) >4. 返回這個新對象; return this; <br> ### **this關鍵字** this關鍵字總是指向一個對象(引用類型),this所指向的對象跟 **函數的調用方式** 有關 ``` // this關鍵字總是指向一個對象(引用類型),this所指向的對象跟 函數的調用方式 有關 console.log(this);// this --> window function person() { console.log(this); } person();// this --> window // person 作為構造函數來使用 var per = new person();// this --> person per.sayHello = function () { console.log(this); } per.sayHello();// this --> person ``` this指向的對象跟 函數的調用方式 有關,如下 >[info]1. 函數作為普通函數的調用中,this --> window >2. 函數作為構造函數的調用中,this --> 當前被創建出來的對象 >3. 函數作為對象的方法調用中,this --> 當前調用該方法的對象 <br> ## 對象的使用 <br> ### 遍歷對象的成員 **語法格式** >[success]通過for..in語法可以遍歷一個對象。格式: >for(var key in obj) { > >} >obj是要遍歷的對象。 key是從obj對象中遍歷出的屬性名, (obj[key])是從obj對象中遍歷出的。 注意:這里只能用中括號語法。 **代碼案例** ``` var obj = {}; for (var i = 0; i < 10; i++) { obj[i] = i * 2; } for(var key in obj) { console.log(key); //對象的屬性名, console.log(obj[key]); //對象的屬性值。 console.log(key + "==" + obj[key]); } ``` ### 刪除對象的成員 **語法格式** >[success]利用delete關鍵字 >delete 成員名; **代碼案例** ``` function fun() { this.name = 'mm'; } var obj = new fun(); console.log(obj.name); // mm delete obj.name; console.log(obj.name); // undefined ``` ## 對象的存儲 ### 基本類型和引用類型的區別 &emsp;&emsp;基本數據類型簡稱基本類型,又叫簡單類型或值類型,引用數據類型簡稱引用類型,又叫復雜類型或對象類型 &emsp;&emsp;基本類型的存儲特點:在存儲數據時,變量中存儲的是值本身,因此基本類型又稱&emsp;&emsp;值類型。引用類型的存儲特點:在存儲數據時,變量中存儲的僅僅是數據的地址(地址又稱引用)。 #### 堆和棧的概念 堆棧空間分配區別:   1、棧(操作系統):由操作系統自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似于數據結構中的棧;   2、堆(操作系統): 存儲引用類型(對象),一般由程序員分配釋放, 若程序員不釋放,由垃圾回收機制回收,分配方式類似于鏈表。 內存中的堆棧可簡化為下圖 ![](https://box.kancloud.cn/5802cbe0164460dc6ab999887adcb1a9_697x488.png) ``` //定義基本數據類型變量 var a = 5; var b = a; a = 6; console.log(a, b); ``` ### 基本類型的數據存儲圖示如下 ![](https://box.kancloud.cn/61e760358bda8ef588f854c1957467a2_731x479.png) 由上圖可以知道,基本類型數據只存儲在占內存中,跟堆內存塊無關。 ### 引用類型在內存中的存儲 &emsp;&emsp;引用類型又稱對象類型,對象是通過new關鍵字創建出來的,所以引用類型的數據存儲圖跟new關鍵字緊密相關。 &emsp;&emsp;當執行new關鍵字時,JS解析器就在堆中開辟一塊內存,并給這塊內存分配一個地址,比如 0xaabb,用于存儲對象的數據(屬性和方法),同時在棧中開辟一塊內存,用于存儲堆內存的地址(0xaabb)。此時棧中存儲的數據就是堆內存塊的地址,所以我們稱 “ 棧上的地址指向了這塊堆內存 ” 。 分析以下代碼在執行過程中的變量的值的變化,并畫出內存圖作進一步分析。 ``` // 定義構造函數 function Person(name, age) { this.name=name; this.age=age; this.sayHi=function () { console.log('你好,我是' + this.name); } } // 調用構造函數 var p1 = new Person('馮寶寶', 100); //將 '馮寶寶', 100 傳入函數Person中,得到對象{name='馮寶寶';age=100;},此時對象的屬性和方法都存儲在堆內存中, var p2=p1; //將對象p1賦值給對象p2,兩個對象名都指向同一個堆內存。 p2.name='張楚嵐'; //將對象p2中的name屬性的值改為'張楚嵐',即將堆內存中的name='馮寶寶'改為name='張楚嵐',此時對象p1的屬性值也隨之給為name='張楚嵐'。 console.log(p1);// 輸出結果:Person?{name: "張楚嵐", age: 100, sayHi: ?} console.log(p2);// 輸出結果:Person?{name: "張楚嵐", age: 100, sayHi: ?} ``` ### 基本類型作為函數的參數 ``` function fn(a, b) { a = a + 2; b = b + 2; console.log(a, b); } // 在函數外部的x,y是否受影響? var x = 2; var y = 3; fn(x, y); console.log(x, y); //注意:函數的參數是局部變量 ``` 基本類型的數據作為函數參數時的存儲圖示如下 ![](https://box.kancloud.cn/df0cbde0bf1d4b27f891da9a025763df_916x408.png) 根據以下存儲圖示可知,在**函數內部修改了變量的值,不影響外部變量原有的值。**我們可以畫出內存圖作進一步分析,就很容易看出不影響的原因。 基本數據類型的數據都是存放在棧內存中,遵循先進后出的原則,當在函數內部修改了變量的值時,實際是新開辟了給內存空間存儲改變后的數據。 ### 引用類型作為函數的參數 ``` // 定義構造函數 function Person(name, age) { this.name=name; this.age=age; this.sayHi=function () { console.log('你好,我是' + this.name); } } ``` 方式一、調用自定義構造函數,分析調用前和調用后數據有什么不同。在函數內部修改變量的值。 ``` // 定義一個函數,參數用于接收一個person對象 function fn(person) { person.name='張楚嵐'; console.log(person); } var p1 = new Person('馮寶寶', 100); fn(p1); console.log(p1); ``` 引用類型的數據作為函數參數時的存儲圖示如下 ![](https://box.kancloud.cn/bbc3e41266aa3e60d2891ada7190003d_990x404.png) 方式二、調用自定義構造函數,分析調用前和調用后數據有什么不同。在函數內部修改變量的值。 ``` // 定義一個函數,參數用于接收一個person對象 function fn(person) { person.name='張楚嵐'; person = new Person('王也',22); console.log(person); } var p1 = new Person('馮寶寶', 100); fn(p1); console.log(p1); ``` 引用類型的數據作為函數參數時的存儲圖示如下 ![](https://box.kancloud.cn/34853185f00fe23690512f8269c28145_986x391.png) ``` // 定義函數 function fn(array) { array[0] = -1; console.log(array);// array[0] -> -1 } //定義一個數組 var arr = [9, 5, 2, 7, 1, 3, 6]; // 調用函數 fn(arr); console.log(arr);// arr[0] -> -1 ``` ![](https://box.kancloud.cn/34205c90582d426cc1539515ccc39728_929x414.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看