面向對象-原型對象

創建對象

Js中可以用構造函數模式創建對象,如:

    function Person(name, age, job) {this.name = name;this.age = age;this.job = job;this.sayName = function () {alert(this.name);}}var person1 = new Person("Nicholas", 29, "aa");var person2 = new Person("YU", 29, "BB");

這里應注意函數名首字母應大寫,按照約定,構造函數始終都應該以一個大寫字母開頭,而非構造函數則應以一個小寫字母開頭。

原型對象

上述方法中,有一個缺點,就是對象中的sayName方法,每次都會重新new一個對象,因此,也就是說不同對象的sayName方法地址是不同的,然而這個方法都只是執行提示姓名,這種創建兩個相同的function,完成同樣的任務,確實沒有必要。所以這存在了缺陷。使用下面的方法可以避免這種缺陷。

????

 function Person() {}Person.prototype.name = "YuKaifei";Person.prototype.age = 25;Person.prototype.job = "SoftWare";Person.prototype.sayName = function () {alert(this.name);}var person1 = new Person();person1.sayName();//YuKaifeivar person2 = new Person();person2.sayName();  //YuKaifei
alert(person1.sayName == person2.sayName); //true

?

理解原型對象

函數

Person

prototype

指向所對應的原型對象

?

函數的原型對象

Person? Prototype? (person的原型對象)

constructor

指向所對應函數(person)的指針

Name

“YuKaiFei”

Age

25

Job

“Soft Ware”

sayName

(function)

?

自定義函數1

Person1

prototype

指向所對應的原型對象

?

自定義函數2

Person2

prototype

指向所對應的原型對象

?

無論什么時候,只要創建了一個新函數,就會為該函數創建一個prototype屬性,這個屬性就指向所對應的原型對象。而默認情況下,原型對象的constructor屬性會指向所對應函數的地址。也就是說這時這兩個對象各有一個屬性,是存放對方的地址的。

當調用一個構造函數創建一個新實例之后,該函數內部也有一個屬性prototype,這個屬性是執行原型對象的地址。也就是說新實例其實與構造函數并沒有直接關系。

需要注意的是,新實例雖然沒有屬性和方法,但是卻可以通過查找對象屬性的方式來調用原型對象中的屬性和方法。

?

當新的實例創建新的屬性之后,如果和原型對象是相同的屬性,那么在下次調用時會調用新實例的屬性,而不是原型對象的屬性。如:

        var person1 = new Person();person1.name="aaaa";var person2 = new Person();alert(person1.name);//aaaa
alert(person2.name);//YuKaifei

?

in 操作符

有兩種方式可以使用in,一種是單獨in,一種是for-in,需要注意的是,無論該屬性是存在于實例中還是存在于原型中,只要存在,就返回true。

例如 alert(name in person1)? 返回true

for (var prop in person1) {if (prop == "name") {alert("name")}}

?

判斷該屬性是否存在實例中的方式是hasOwnPropery()方法。

例如:person1.hasOwnProperty(“Name”) 返回true

???????? Person2.hasOwnProperty(“Name”) 返回false

?

獲取對象上所有可枚舉的實例屬性:

 var keys = Object.keys(Person.prototype);alert(keys); //name,age,job,syName,注意keys是一個數組。

更簡單的原型語法—存在缺陷

Person.prototype = {name: "Nicholas",age: 29,jon: "SowfWare",syaName: function () {alert(this.name);}}

可以使用這種方法更簡單的創建原型,但需要注意的是,這種寫法相當于重寫了原型對象,所有consturctor屬性是新的,即不在指向person。如:

function Person() {}var friend = new Person();Person.prototype = {name: "Nicholas",age: 29,jon: "SowfWare",syaName: function () {alert(this.name);}}friend.sayName(); //error

?

上面代碼會報錯,原因在與重寫了原型對象,指向丟失,也就是切斷了現有原型與之前已經存在的對象之間的聯系。如果避免這種方法可以在聲明原型中指定: constructor:Person

原生對象的原型—String、Array

原型的模式體現在所有原生的引用類型,例如object、array、string等,都在其構造函數的原型上定義了方法,例如在Array.prototype中可以找到sort()方法,在string.prototype可以找到substring()方法。

通過原生對象的原型,不僅可以獲得所有默認方法的引用,也可以隨意的修改原生對象的原型,因此可以隨時添加方法。例如:

為String添加一個名為startsWith()?方法。

String.prototype.startsWith = function (text) {return this.indexOf(text) == 0;}var msg = "Hello world!";alert(msg.startsWith("Hello")); //true

優化原型對象的缺陷

原型對象為了省略函數傳遞初始化這一環節,結果所有的實例在默認情況下都會取得相同的值,這對于值類型屬性共享還可以,但是對于引用類型則會存在問題。如:

?

function Person() {}Person.prototype = {name: "Nicholas",age: 29,jon: "SowfWare",friends:["Yu","Kai"],syaName: function () {alert(this.name);}}var person1 = new Person;person1.name = "yy";var person2 = new Person;
alert(person1.name);
//yy alert(person2.name); //Nicholas person1.friends.push("Fei");alert(person1.friends); //YuKaiFei alert(person2.friends); //YuKaiFei

可以看到值類型并沒有什么影響,但因為引用類型的特殊,所有實例的值都將會被改變。

所有最好采用動態原型模式

動態原型模式-聲明原型的推薦方式

 function Person(name, age, job) {this.name = name;this.age = age;this.job = job;this.friends = ["Yu", "kai"];if (typeof  this.sayName != "function") {this.sayName = function () {alert(this.name);};}}var f1 = new Person("Y", 29, "s");var f2 = new Person("Y", 29, "s");f1.friends.push("Fei");alert(f1.friends); //yu,kai,fei
alert(f2.friends);//yu,kai

?

轉載于:https://www.cnblogs.com/y8932809/p/5386925.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374855.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374855.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374855.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

索引類型

1.B樹索引 在Oracle中是通用索引,是創建索引時的默認索引。B樹索引可以是單列索引,也可以是組合/復合索引。B樹索引最多可以包括22列。 2.位圖索引 位圖索引時決策支持系統(DSS)和數據倉庫的理想選擇,它們不應該用于事…

C語言條件運算符

先看一個error error: lvalue required as left operand of assignment| i 0 ? X 1.0 : X * x;修改后 i 0 ? (X 1.0) : (X * x);也就是說條件運算符可以執行語句,當是賦值語句時要加括號規定優先級,不然會干擾程序判斷。 因為條件運算符作為三目…

EJB 3.0注入和查找簡介

介紹 Enterprise JavaBeans Specification v。3.0引入了簡化的,基于注釋的API,用于EJB注入和查找。 EJB 3.0現在是POJO,可以使用簡單的注釋將其注入其他組件(例如EJB和Servlet)。 EJB 3.0是Java EE 6的許多其他基于POJ…

SignalR + MVC5 簡單示例

SignalR MVC5 簡單示例 原文:SignalR MVC5 簡單示例本文和前一篇文章很類似,只不過是把 SignalR 應用在了 MVC 中 新建項目,選擇 MVC 模板 安裝 SignalR Install-Package Microsoft.AspNet.SignalR 在項目中添加文件夾 Hubs 在 Hubs 文件夾中添加 Sign…

Java內存模型–快速概述和注意事項

在計算中, 內存模型描述了線程如何通過內存進行交互,或更一般地,它指定了為分段內存或分頁內存平臺生成代碼時允許編譯器進行的假設。 在給定程序和該程序的執行跟蹤的情況下,它實質上描述了執行跟蹤是否是該程序的合法執行。 Jav…

6-7 統計某類完全平方數 (20 分)

本題要求實現一個函數,判斷任一給定整數N是否滿足條件:它是完全平方數,又至少有兩位數字相同,如144、676等。 函數接口定義: int IsTheNumber ( const int N );其中N是用戶傳入的參數。如果N滿足條件,則該…

C#中數組、ArrayList和List三者的區別(轉) ,加修改

在C#中數組&#xff0c;ArrayList&#xff0c;List都能夠存儲一組對象&#xff0c;那么這三者到底有什么樣的區別呢。 數組 數組在C#中最早出現的。在內存中是連續存儲的&#xff0c;所以它的索引速度非常快&#xff0c;而且賦值與修改元素也很簡單。 <span style"font…

phpmyadmin mysql Access denied for user 'root'@'localhost'問題解決

centos6.4 32位的vps上裝了lnmp以后&#xff0c;phpmyadmin無法連接mysql服務器&#xff0c;ssh命令行里mysql -uroot -p 命令后老是出現拒絕連接的情況。php程序里也是拒絕連接。嘗試過修改phpmyadmin的config.inc.php文件&#xff0c;嘗試過修改my.cnf文件&#xff0c;嘗試過…

帶有Spring和Maven教程的JAX–WS

Spring框架通過JAX-WS提供對Web服務的遠程支持&#xff0c;實際上&#xff0c;如Spring 參考文檔中所述 &#xff0c;有三種將Spring POJO服務公開為JAX-WS Web服務的方式&#xff1a; 公開基于Servlet的Web服務&#xff08;適用于Java EE 5環境&#xff09; 導出獨立的Web服…

7-2 然后是幾點 (15 分)

7-2 然后是幾點 (15 分) 有時候人們用四位數字表示一個時間&#xff0c;比如 1106 表示 11 點零 6 分。現在&#xff0c;你的程序要根據起始時間和流逝的時間計算出終止時間。 讀入兩個數字&#xff0c;第一個數字以這樣的四位數字表示當前時間&#xff0c;第二個數字表示分鐘…

CXF學習(2) helloworld

0.新建一個項目取名wsserver. pom.xml 文件如下 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd…

Hive 接口介紹(Web UI/JDBC)

Hive 接口介紹&#xff08;Web UI/JDBC&#xff09; 實驗簡介 本次實驗學習 Hive 的兩種接口&#xff1a;Web UI 以及 JDBC。 一、實驗環境說明 1. 環境登錄 無需密碼自動登錄&#xff0c;系統用戶名shiyanlou&#xff0c;密碼shiyanlou 2. 環境介紹 本實驗環境采用帶桌面的Ubu…

Java最佳實踐– Char到Byte和Byte到Char的轉換

在使用Java編程語言時&#xff0c;我們將繼續討論與建議的實踐有關的系列文章&#xff0c;我們將討論String性能調優。 特別是&#xff0c;我們將重點介紹使用默認編碼時如何有效地處理字符到字節和字節到字符的轉換。 本文總結了兩種提議的自定義方法與兩種經典方法&#xff0…

IOS-C文件的創建于初始化函數.void init() write_file()

//文件初始化 void init(){ FILE * fpNULL; fpfopen("telbook.data", "rb"); int count0; if (fpNULL) //沒有這個文件就把這個文件創建出來 { fpfopen("tellbook.data", "wb"); fwrite(&count, sizeof(count), 1, fp); fclose(…

7-3 逆序的三位數 (10 分)

7-3 逆序的三位數 (10 分) 程序每次讀入一個正3位數&#xff0c;然后輸出按位逆序的數字。注意&#xff1a;當輸入的數字含有結尾的0時&#xff0c;輸出不應帶有前導的0。比如輸入700&#xff0c;輸出應該是7。 輸入格式&#xff1a; 每個測試是一個3位的正整數。 輸出格式&a…

拋棄優啟Grub4dos和PE大多數時間可以這樣用

拋棄優啟Grub4dos和PE大多數時間可以這樣用 在能夠進入Windows的情況下&#xff0c;Grub4dos和PE大多數時間可以這樣用 http://yunpan.cn/cyuuUtUQMfmGN 提取碼 c2acGrub4dos的出現顛覆了傳統的EZBOOT光盤啟動模式&#xff0c;很多人用grub4dos來實現優盤啟動&#xff0c;同時g…

Java最佳實踐–隊列之戰和鏈接的ConcurrentHashMap

在使用Java編程語言時&#xff0c;我們將繼續討論與建議的實踐有關的系列文章&#xff0c;我們將在四個具有相關語義的流行Queue實現類之間進行性能比較。 為了使事情變得更現實&#xff0c;我們將在多線程環境下進行測試&#xff0c;以討論和演示如何將ArrayBlockingQueue &am…

HDU 5652 India and China Origins(二分 + BFS)

本文鏈接:http://www.cnblogs.com/Ash-ly/p/5398867.html 題意&#xff1a; 中國和印度之間有一片地方&#xff0c;把這片地方抽象化&#xff0c;于是就可以看成一個N * M矩陣&#xff0c;其中黑色的代表高山不能走過去&#xff0c;白色的代表平原&#xff0c;可以通行,人每次可…

C語言%.2f四舍五入

#include <stdio.h> int main() {double d 1.199;printf("%.2f", d);return 0; }輸出1.20 如果不想讓其四舍五入可以這樣&#xff1a; #include <stdio.h> #include <math.h> int main() {double d 1.199;printf("%.2f", floor(d * 1…

關于使用racthet的push.js

racthet的push是用來跳轉另外一個頁面的效果的。但是必須在服務器的環境下支持。如果想要讓本地html訪問支持的話需要添加 轉載于:https://www.cnblogs.com/djawh/p/4623925.html