JavaScript 面向對象的程序設計1

一、理解對象

1.創建一個對象,然后給這個對象新建屬性和方法。
①常見的創建方式

var person = new Object(); //創建一個Object 對象person.name = 'XIE'; //創建一個name 屬性并賦值person.age = 20; //創建一個age 屬性并賦值person.sayName = function () { //創建一個run()方法并返回值return this.name; //this指的是person本身};

②字面量的形式

var person = {name:"xie",age:20,job:"學生",sayName:function(){return this.name;}
}

2.數據屬性
數據屬性有4個描述其行為的特性。

特性默認值含義
configurabletrue是否可配置,表示能否刪除屬性重新定義,能否修改屬性的特性,能否修改為訪問器屬性。
enumerabletrue是否可枚舉
writabletrue是否可修改屬性值
valueundefined屬性的數據值

注:configurable特性一旦設置為false后,則不能再變為true.

var person={};
Object.defineProperty(person,"name",{configurable:true,enumerable:true,writable:true,value:"xie"
})

3.訪問器屬性

特性默認值含義
configurabletrue是否可配置,表示能否刪除屬性重新定義,能否修改屬性的特性,能否修改為訪問器屬性。
enumerabletrue是否可枚舉
getundefined讀取屬性時調用
setundefined寫入屬性時調用

二、創建對象

1.工廠模式

function createObject(name, age) { //集中實例化的函數var obj = new Object();obj.name = name;obj.age = age;obj.run = function () {return this.name + this.age + '運行中...';};return obj;
}
var box1 = createObject('Lee', 100); //第一個實例
var box2 = createObject('Jack', 200); //第二個實例

工廠模式解決了重復實例化的問題,但還有一個問題,那就是識別問題,因為根本無法弄清楚一個對象的類型。

2.構造函數模式

function Person(name,age){this.name = name;this.age = age;this.run = function(){alert(this.name);}
}
var person1 = new Person("Lee",100);
var person2 = new Person("Jack",200);

使用了構造函數的方法,和使用工廠模式的方法他們不同之處如下:

  1. 構造函數方法沒有顯示的創建對象(new Object());
  2. 直接將屬性和方法賦值給this 對象;
  3. 沒有renturn 語句。

構造函數的方法有一些規范:

  • .函數名和實例化構造名相同且大寫,(PS:非強制,但這么寫有助于區分構造函數和普通函數);
  • 通過構造函數創建對象,必須使用new 運算符。

使用new操作符創建實例時,執行過程如下:

  1. 創建一個新對象;
  2. 將構造函數的作用域賦給新對象(因此this就指向了這個對象);
  3. 執行構造函數中的代碼(為這個新對象添加屬性);
  4. 返回新對象

    使用構造函數的主要問題,就是每個方法都要再每個實例上重新創建一遍。通過下面可知不一樣:

alert(person1.run == person2.run);  //false

3.原型模式

我們創建的每個函數都有一個prototype(原型)屬性,這個屬性是一個指針,指向一個對象,它的用途是包含可以由特定類型的所有實例共享的屬性和方法。使用原型的好處可以讓所有對象實例共享它所包含的屬性和方法。也就是說,不必在構造函數中定義對象信息,而是可以直接將這些信息添加到原型中。

3.1常見的語法

// 原型模式
function Box() {} //聲明一個構造函數
Box.prototype.name = 'Lee'; //在原型里添加屬性
Box.prototype.age = 100;
Box.prototype.run = function () { //在原型里添加方法return this.name + this.age + '運行中...';
};
//比較一下原型內的方法地址是否一致:
var box1 = new Box();
var box2 = new Box();
alert(box1.run == box2.run); //true,方法的引用地址保持一致

下面可通過圖進一步了解

構造函數模式

原型模式
在原型模式聲明中,多了兩個屬性,這兩個屬性都是創建對象時自動生成的。proto屬性是實例指向原型對象的一個指針,ECMAScript5稱這個指針為[[Prototype]],它的作用就是指向構造函數的原型屬性constructor。

isPrototypeOf()方法來判斷一個對象是否指向了該構造函數的原型

alert(Box.prototype.isPrototypeOf(box1)); //true,只要實例化對象,即都會指向

Object.getPrototype()方法返回[[Prototype]]的值。IE9+,Firefox3.5+,Safari5+,Opera12+ 和Chrome支持

alert(Object.getPrototype(box1).name);  //Lee

原型模式的執行流程:

  1. .先查找構造函數實例里的屬性或方法,如果有,立刻返回;
  2. 如果構造函數實例里沒有,則去它的原型對象里找,如果有,就返回;

hasOwnProperty()函數判斷構造函數的實例中是否有該屬性。

alert(box.hasOwnProperty('name')); //實例里有返回true,否則返回false

in操作符會在通過對象能夠訪問給定屬性時返回 true,無論該屬性存在于實例中還是原型中。

alert('name' in box); //true,存在實例中或原型中
function isProperty(object, property) { //判斷原型中是否存在屬性return !object.hasOwnProperty(property) && (property in object);
}

3.2更簡單的原型語法

為了讓屬性和方法更好的體現封裝的效果,并且減少不必要的輸入,原型的創建可以使用字面量的方式:

function Box() {};
Box.prototype = { //使用字面量的方式name : 'Lee',age : 100,run : function () {return this.name + this.age + '運行中...';}
};

使用構造函數創建原型對象和使用字面量創建對象在使用上基本相同,但還是有一些區別,字面量創建的方式使用constructor 屬性不會指向實例,而會指向Object,構造函數創建的方式則相反。

var box = new Box();
alert(box instanceof Box);  //true
alert(box instanceof Object);  //true
alert(box.constructor == Box); //字面量方式,返回false,否則,true
alert(box.constructor == Object); //字面量方式,返回true,否則,false

如果想讓字面量方式的constructor 指向實例對象,可以如下所示

function Box() {};
Box.prototype = { //使用字面量的方式constructor : Box, //直接強制指向即可name : 'Lee',age : 100,run : function () {return this.name + this.age + '運行中...';}
};

重設constructor會導致它的enumerable特性被修改為true,默認情況下,原生的constructor是不可枚舉的,可使用Object.defineProperty()方法重設構造函數。

Object.defineProperty(Box.prototype,"constructor",{enumerable:false,value:Box
});

原型的聲明是有先后順序的,所以,重寫的原型會切斷之前的原型。

function Box() {};
Box.prototype = { //原型被重寫了constructor : Box,name : 'Lee',age : 100,run : function () {return this.name + this.age + '運行中...';}
};
Box.prototype = {age = 200
};
var box = new Box(); //在這里聲明
alert(box.run()); //erroe,因為box 只是最初聲明的原型

3.3原型對象的問題

原型模式創建對象也有自己的缺點,它省略了構造函數傳參初始化這一過程,帶來的缺點就是初始化的值都是一致的。而原型最大的缺點就是它最大的優點,那就是共享。原型中所有屬性是被很多實例共享的,共享對于函數非常合適,對于包含基本值的屬性也還可以。但如果屬性包含引用類型,就存在一定的問題:

function Box() {};
Box.prototype = {constructor : Box,name : 'Lee',age : 100,family : ['父親', '母親', '妹妹'], //添加了一個數組屬性run : function () {return this.name + this.age + this.family;}
};
var box1 = new Box();
box1.family.push('哥哥'); //在實例中添加'哥哥'
alert(box1.run());
var box2 = new Box();
alert(box2.run()); //共享帶來的麻煩,也有'哥哥'了

4.動態原型模式

為了解決構造傳參和共享問題,可以組合構造函數+原型模式,即動態原型模式。

function Box(name ,age) { //將所有信息封裝到函數體內this.name = name;   //不共享的使用構造函數形式this.age = age;if (typeof this.run != 'function') { //僅在第一次調用的初始化Box.prototype.run = function () {   //共享的使用原型模式return this.name + this.age + '運行中...';};}
}
var box = new Box('Lee', 100);
alert(box.run());

當第一次調用構造函數時,run()方法發現不存在,然后初始化原型。當第二次調用,就不會初始化,并且第二次創建新對象,原型也不會再初始化了。這樣及得到了封裝,又實現了原型方法共享,并且屬性都保持獨立。
PS:使用動態原型模式,要注意一點,不可以再使用字面量的方式重寫原型,因為會切斷實例和新原型之間的聯系。

5.寄生構造函數模式

寄生構造函數,其實就是工廠模式+構造函數模式。這種模式比較通用,但不能確定對象關系。

function myString(string) {var str = new String(string);str.addstring = function () {return this + ',被添加了!';};return str;
}
var box = new myString('Lee'); //比直接在引用原型添加要繁瑣好多
alert(box.addstring());

使用場景:要創建一個具有額外方法的引用類型時。

6.穩妥構造函數模式

在一些安全的環境中,比如禁止使用this 和new,這里的this 是構造函數里不使用this,這里的new 是在外部實例化構造函數時不使用new。

function Box(name , age) {var obj = new Object();obj.run = function () {return name + age + '運行中...'; //直接打印參數即可};return obj;
}
var box = Box('Lee', 100); //直接調用函數
alert(box.run());

PS:穩妥構造函數和寄生類似。

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

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

相關文章

Zookeeper 使用

安裝和配置詳解 本文介紹的 Zookeeper 是以 3.2.2 這個穩定版本為基礎,最新的版本可以通過官網 http://hadoop.apache.org/zookeeper/來獲取,Zookeeper 的安裝非常簡單,下面將從單機模式和集群模式兩個方面介紹 Zookeeper 的安裝和配置。 單…

Asp.Net Core 工作單元 UnitOfWork UOW

Asp.Net Core 工作單元示例 來自 ABP UOW 去除所有無用特性 代碼下載 : 去除所有無用特性版本,原生AspNetCore實現 差不多 2278 行代碼: 鏈接:https://pan.baidu.com/s/1NoEIDSAPNr46xNHYEx9KCA 提取碼:570i 包含C…

網站性能優化--CRP

網站性能優化–CRP 為了把HTML、CSS和JavaScript轉化成活靈活現、絢麗多彩的網頁,瀏覽器需要處理一系列的中間過程,優化性能其實就是了解這個過程中發生了什么-即CRP(Critical Rendering Path,關鍵渲染路徑)。首先,我們從頭開始快…

Dubbo+zookeeper基礎講解

一、dubbo是什么? 1)本質:一個Jar包,一個分布式框架,,一個遠程服務調用的分布式框架。 既然是新手教學,肯定很多同學不明白什么是分布式和遠程服務調用,為什么要分布式,為什么要遠程調用。我簡…

What Are You Talking About HDU1075

一開始我也想用map 但是處理不好其他字符。。 看了題解 多多學習&#xff01; 很巧妙 就是粗暴的一個字符一個字符的來 分為小寫字母和非小寫字母兩個部分 一但單詞結束的時候就開始判斷。 #include<bits/stdc.h> using namespace std;int main() {string a,b;map&l…

開通博客第一天

今天是開通博客第一天&#xff0c; 第一次寫博客&#xff0c;也不知道寫什么&#xff0c; 以后寫點技術文&#xff0c;把我的經驗分享給大家&#xff0c; 不對的地方請大家指正&#xff0c;一起進步。我要把我每遇到的難題以及學到的知識和技術為大家踩坑&#xff0c; 做研究。…

學習File API用于前端讀取文件

1. File API簡介 File API對于某些專門的網站的不可或缺的。現在常用它實現對文件的預覽等功能。 File API規定怎么從硬盤上提取文件&#xff0c;直接交給在網頁中運行中的Javascript代碼。然后代碼可以打開文件探究數據&#xff0c;無論是本地文件還是其他文件。注意&#x…

kafka筆記1

Kafka是一款基于發布和訂閱的消息系統。一般被稱為分布式提交日志或分布式流平臺。 Kafka系統是按照一定的順序持久化保存的&#xff0c;可以按需讀取。 Kafka的數據單元被稱為消息。類似于數據庫中表的一行記錄&#xff0c;消息由字節組成&#xff0c;所以沒有特別的格式和含義…

Dubbo入門教程

服務端&#xff08;dubbo-server&#xff09; 1. pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaL…

NSAssert和NSParameterAssert

2016.05.05 18:34* 字數 861 閱讀 5127評論 0喜歡 17https://www.jianshu.com/p/3072e174554fNSAssert和NSParameterAssert在開發環境中經常被使用&#xff0c;調試和驗證代碼參數的完整性&#xff0c;斷言為真&#xff0c;則表明程序運行正常&#xff0c;而斷言為假&#xff0…

【PAT】B1070 結繩(25 分)

此題太給其他25分的題丟人了&#xff0c;只值15分 注意要求最終結果最長&#xff0c;而且向下取整 #include<stdio.h> #include<algorithm> using namespace std; float arr[10005]; int main(){int N;scanf("%d",&N);for(int i0;i<N;i)//輸入數據…

Java代碼實現負載均衡五種算法

前言&#xff1a; 負載均衡是為了解決并發情況下&#xff0c;多個請求訪問&#xff0c;把請求通過提前約定好的規則轉發給各個server。其中有好幾個種經典的算法。在用java代碼編寫這幾種算法之前&#xff0c;先來了解一下負載均衡這個概念。 1.概念 負載&#xff0c;從字面…

使用Nodejs發送郵件

嘗試用了Nodemailer來發送郵件&#xff0c;結果成功了&#xff0c;雖然是相對比較簡單的&#xff0c;但還是記錄一下吧。 Nodemailer 是 Node.js 應用程序的一個模塊&#xff0c;可以方便地發送電子郵件。 使用 # 初始化 pageage.json 文件 $ npm init # 安裝依賴 $ npm ins…

HTTP同源策略

同源策略是web安全策略中的一種&#xff0c;非常重要。 同源策略明確規定&#xff1a;不同域的客戶端在沒有明確授權的情況下&#xff0c;不能讀寫對方的資源。 簡單說來就是web瀏覽器允許第一個頁面的腳本訪問訪問第二個頁面的數據&#xff0c;但是也只有在兩個頁面有相同的…

Spring Cloud 微服務架構

一、分布式服務框架的發展 1.1 第一代服務框架   代表&#xff1a;Dubbo(Java)、Orleans(.Net)等 特點&#xff1a;和語言綁定緊密 1.2 第二代服務框架   代表&#xff1a;Spring Cloud等 現狀&#xff1a;適合混合式開發&#xff08;例如借助Steeltoe OSS可以讓ASP.Ne…

JZOJ 4421. aplusb

4421. aplusb Time Limits: 1000 ms Memory Limits: 524288 KB Detailed Limits Goto ProblemSetDescription SillyHook要給小朋友出題了&#xff0c;他想&#xff0c;對于初學者&#xff0c;第一題肯定是ab 啊&#xff0c;但當他出完數據后神奇地發現.in不見了&#xff0c…

跨域資源共享CORS詳解

最近深入了解了CORS的相關東西&#xff0c;覺得阮一峰老師的文章寫得最詳細易懂了&#xff0c;所有轉載作為學習筆記。 原文地址&#xff1a;跨域資源共享 CORS 詳解 CORS是W3C的一個標準&#xff0c;全稱是跨域資源共享&#xff08;Cross-origin resource sharing&#xff0…

計算機網絡(十),HTTP的關鍵問題

目錄 1.在瀏覽器地址欄鍵入URL&#xff0c;按下回車之后經歷的流程 2.HTTP狀態碼 3.GET請求和POST請求的區別 4.Cookie和Session的區別 5.IPV4和IPV6 十、HTTP的關鍵問題 1.在瀏覽器地址欄鍵入URL&#xff0c;按下回車之后經歷的流程 &#xff08;1&#xff09;DNS解析 &#x…

云技術

云技術是指在廣域網或局域網內將硬件、軟件、網絡等系列資源統一起來&#xff0c;實現數據的計算、儲存、處理和共享的一種托管技術。

vue中 mock使用教程

//mock/index.js import Mock from mockjs //引入mockjs&#xff0c;npm已安裝 import { Random,toJSONSchema } from mockjs // 引入random對象,隨機生成數據的對象&#xff0c;&#xff08;與占位符一樣&#xff09; Mock.setup({timeout:1000 //設置請求延時時間 }) const …