中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

javascript是否支持面向對象

發布時間:2022-03-03 15:52:27 來源:億速云 閱讀:131 作者:iii 欄目:web開發

本篇內容介紹了“javascript是否支持面向對象”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

JavaScript是支持面向對象的;面向對象編程是用抽象方式創建基于現實世界模型的一種編程模式,面向對象使用先前建立的范例,包括模塊化、多態和封裝幾種技術,包括JavaScript在內的許多流行編程語言都支持面向對象編程。

本教程操作環境:windows10系統、javascript1.8.5版、Dell G3電腦。

javascript支持面向對象

JavaScript 的核心是支持面向對象的,同時它也提供了強大靈活的 OOP 語言能力。本文從對面向對象編程的介紹開始,帶您探索 JavaScript 的對象模型,最后描述 JavaScript 當中面向對象編程的一些概念。

面向對象編程

面向對象編程是用抽象方式創建基于現實世界模型的一種編程模式。它使用先前建立的范例,包括模塊化,多態和封裝幾種技術。今天,許多流行的編程語言(如Java,JavaScript,C#,C+ +,Python,PHP,Ruby 和 Objective-C)都支持面向對象編程(OOP)。

相對于「一個程序只是一些函數的集合,或簡單的計算機指令列表。」的傳統軟件設計觀念而言,面向對象編程可以看作是使用一系列對象相互協作的軟件設計。 在 OOP 中,每個對象能夠接收消息,處理數據和發送消息給其他對象。每個對象都可以被看作是一個擁有清晰角色或責任的獨立小機器。

面向對象程序設計的目的是在編程中促進更好的靈活性和可維護性,在大型軟件工程中廣為流行。憑借其對模塊化的重視,面向對象的代碼開發更簡單,更容易理解,相比非模塊化編程方法, 它能更直接地分析, 編碼和理解復雜的情況和過程。

Namespace

命名空間允許開發人員在一個獨特,應用相關的名字的名稱下捆綁所有功能的容器。

Class 類

定義對象的特征。它是對象的屬性和方法的模板定義。

Object 對象

類的一個實例。

Property 屬性

對象的特征,比如顏色。

Method 方法

對象的能力,比如行走。

Constructor 構造函數

對象初始化的瞬間,被調用的方法。通常它的名字與包含它的類一致。

Inheritance 繼承

一個類可以繼承另一個類的特征。

Encapsulation 封裝

一種把數據和相關的方法綁定在一起使用的方法。

Abstraction 抽象

結合復雜的繼承,方法,屬性的對象能夠模擬現實的模型。

Polymorphism 多態

多意為「許多」,態意為「形態」。不同類可以定義相同的方法或屬性。

原型編程

基于原型的編程不是面向對象編程中體現的風格,且行為重用(在基于類的語言中也稱為繼承)是通過裝飾它作為原型的現有對象的過程實現的。這種模式也被稱為弱類化,原型化,或基于實例的編程。

原始的(也是最典型的)基于原型語言的例子是由大衛·安格爾和蘭德爾·史密斯開發的。然而,弱類化的編程風格近來變得越來越流行,并已被諸如JavaScript,Cecil,NewtonScript,IO,MOO,REBOL,Kevo,Squeak(使用框架操縱Morphic組件),和其他幾種編程語言采用。

JavaScript面向對象編程

命名空間

命名空間是一個容器,它允許開發人員在一個獨特的,特定于應用程序的名稱下捆綁所有的功能。 在JavaScript中,命名空間只是另一個包含方法,屬性,對象的對象。

注意:需要認識到重要的一點是:與其他面向對象編程語言不同的是,Javascript中的普通對象和命名空間在語言層面上沒有區別。這點可能會讓JavaScript初學者感到迷惑。

創造的JavaScript命名空間背后的想法很簡單:一個全局對象被創建,所有的變量,方法和功能成為該對象的屬性。使用命名空間也最大程度地減少應用程序的名稱沖突的可能性。

我們來創建一個全局變量叫做 MYAPP

// 全局命名空間
var MYAPP = MYAPP || {};

在上面的代碼示例中,我們首先檢查MYAPP是否已經被定義(是否在同一文件中或在另一文件)。如果是的話,那么使用現有的MYAPP全局對象,否則,創建一個名為MYAPP的空對象用來封裝方法,函數,變量和對象。

我們也可以創建子命名空間:

// 子命名空間
MYAPP.event = {};

下面是用于創建命名空間和添加變量,函數和方法的代碼寫法:

// 給普通方法和屬性創建一個叫做MYAPP.commonMethod的容器
MYAPP.commonMethod = {
  regExForName: "", // 定義名字的正則驗證
  regExForPhone: "", // 定義電話的正則驗證
  validateName: function(name){
    // 對名字name做些操作,你可以通過使用“this.regExForname”
    // 訪問regExForName變量
  },
  
  validatePhoneNo: function(phoneNo){
    // 對電話號碼做操作
  }
}
 
// 對象和方法一起申明
MYAPP.event = {
    addListener: function(el, type, fn) {
    //  代碼
    },
   removeListener: function(el, type, fn) {
    // 代碼
   },
   getEvent: function(e) {
   // 代碼
   }
   
   // 還可以添加其他的屬性和方法
}
 
//使用addListener方法的寫法:
MYAPP.event.addListener("yourel", "type", callback);

標準內置對象

JavaScript有包括在其核心的幾個對象,例如,Math,Object,Array和String對象。下面的例子演示了如何使用Math對象的random()方法來獲得一個隨機數。

console.log(Math.random());

注意:這里和接下來的例子都假設名為 console.log 的方法全局有定義。console.log 實際上不是 JavaScript 自帶的。

查看 JavaScript 參考:全局對象 了解 JavaScript 內置對象的列表。

JavaScript 中的每個對象都是 Object 對象的實例且繼承它所有的屬性和方法。

自定義對象

JavaScript 是一種基于原型的語言,它沒類的聲明語句,比如 C+ + 或 Java 中用的。這有時會對習慣使用有類申明語句語言的程序員產生困擾。相反,JavaScript可用方法作類。定義一個類跟定義一個函數一樣簡單。在下面的例子中,我們定義了一個新類Person。

function Person() { }
// 或
var Person = function(){ }

對象(類的實例)

我們使用 new obj 創建對象 obj 的新實例, 將結果(obj 類型)賦值給一個變量方便稍后調用。

在下面的示例中,我們定義了一個名為Person的類,然后我們創建了兩個Person的實例(person1 and person2)。

function Person() { }
var person1 = new Person();
var person2 = new Person();

注意:有一種新增的創建未初始化實例的實例化方法,請參考 Object.create 。

構造器

在實例化時構造器被調用 (也就是對象實例被創建時)。構造器是對象中的一個方法。 在JavaScript中函數就可以作為構造器使用,因此不需要特別地定義一個構造器方法,每個聲明的函數都可以在實例化后被調用執行。

構造器常用于給對象的屬性賦值或者為調用函數做準備。 在本文的后面描述了類中方法既可以在定義時添加,也可以在使用前添加。

在下面的示例中, Person類實例化時構造器調用一個 alert函數。

function Person() {
  alert('Person instantiated');
}
 
var person1 = new Person();
var person2 = new Person();

屬性 (對象屬性)

屬性就是 類中包含的變量;每一個對象實例有若干個屬性. 為了正確的繼承,屬性應該被定義在類的原型屬性 (函數)中。

可以使用 關鍵字 this調用類中的屬性, this是對當前對象的引用。 從外部存取(讀/寫)其屬性的語法是: InstanceName.Property; 這與C++,Java或者許多其他語言中的語法是一樣的 (在類中語法 this.Property 常用于set和get屬性值)

在下面的示例中,我們為定義Person類定義了一個屬性 firstName 并在實例化時賦初值。

function Person(firstName) {
  this.firstName = firstName;
  alert('Person instantiated');
}
 
var person1 = new Person('Alice');
var person2 = new Person('Bob');
 
// Show the firstName properties of the objects
alert('person1 is ' + person1.firstName); // alerts "person1 is Alice"
alert('person2 is ' + person2.firstName); // alerts "person2 is Bob"

方法(對象屬性)

方法與屬性很相似, 不同的是:一個是函數,另一個可以被定義為函數。 調用方法很像存取一個屬性,  不同的是add () 在方法名后面很可能帶著參數。為定義一個方法, 需要將一個函數賦值給類的 prototype 屬性; 這個賦值給函數的名稱就是用來給對象在外部調用它使用的。

在下面的示例中,我們給Person類定義了方法 sayHello(),并調用了它。

function Person(firstName) {
  this.firstName = firstName;
}
 
Person.prototype.sayHello = function() {
  alert("Hello, I'm " + this.firstName);
};
 
var person1 = new Person("Alice");
var person2 = new Person("Bob");
 
// call the Person sayHello method.
person1.sayHello(); // alerts "Hello, I'm Alice"
person2.sayHello(); // alerts "Hello, I'm Bob"

在JavaScript中方法通常是一個綁定到對象中的普通函數, 這意味著方法可以在其所在context之外被調用。 思考下面示例中的代碼:

function Person(firstName) {
  this.firstName = firstName;
}
 
Person.prototype.sayHello = function() {
  alert("Hello, I'm " + this.firstName);
};
 
var person1 = new Person("Alice");
var person2 = new Person("Bob");
var helloFunction = person1.sayHello;
 
person1.sayHello();                                 // alerts "Hello, I'm Alice"
person2.sayHello();                                 // alerts "Hello, I'm Bob"
helloFunction();                                    // alerts "Hello, I'm undefined" (or fails with a TypeError in strict mode)
console.log(helloFunction === person1.sayHello);          // logs true
console.log(helloFunction === Person.prototype.sayHello); // logs true
helloFunction.call(person1);                        // logs "Hello, I'm Alice"  

如上例所示, 所有指向sayHello函數的引用 ,包括 person1, Person.prototype, 和 helloFunction 等, 均引用了相同的函數.

在調用函數的過程中,this的值取決于我們怎么樣調用函數.  在通常情況下,我們通過一個表達式person1.sayHello()來調用函數:即從一個對象的屬性中得到所調用的函數。此時this被設置為我們取得函數的對象(即person1)。這就是為什么person1.sayHello() 使用了姓名“Alice”而person2.sayHello()使用了姓名“bob”的原因。

然而我們使用不同的調用方法時, this的值也就不同了。當從變量 helloFunction()中調用的時候, this就被設置成了全局對象 (在瀏覽器中即window)。由于該對象 (非常可能地) 沒有firstName 屬性, 我們得到的結果便是"Hello, I'm undefined". (這是松散模式下的結果, 在 嚴格模式中,結果將不同(此時會產生一個error)。 但是為了避免混淆,我們在這里不涉及細節) 。另外,我們可以像上例末尾那樣,使用Function#call (或者Function#apply)顯式的設置this的值。

更多有關信息請參考 Function#call and Function#apply

繼承

創建一個或多個類的專門版本類方式稱為繼承(Javascript只支持單繼承)。 創建的專門版本的類通常叫做子類,另外的類通常叫做父類。 在Javascript中,繼承通過賦予子類一個父類的實例并專門化子類來實現。在現代瀏覽器中你可以使用 Object.create 實現繼承。

JavaScript 并不檢測子類的 prototype.constructor (見 Object.prototype), 所以我們必須手動申明它。

在下面的例子中, 我們定義了 Student類作為 Person類的子類。 之后我們重定義了sayHello() 方法并添加了 sayGoodBye() 方法。

// 定義Person構造器
function Person(firstName) {
  this.firstName = firstName;
}
 
// 在Person.prototype中加入方法
Person.prototype.walk = function(){
  alert("I am walking!");
};
Person.prototype.sayHello = function(){
  alert("Hello, I'm " + this.firstName);
};
 
// 定義Student構造器
function Student(firstName, subject) {
  // 調用父類構造器, 確保(使用Function#call)"this" 在調用過程中設置正確
  Person.call(this, firstName);
 
  // 初始化Student類特有屬性
  this.subject = subject;
};
 
// 建立一個由Person.prototype繼承而來的Student.prototype對象.
// 注意: 常見的錯誤是使用 "new Person()"來建立Student.prototype.
// 這樣做的錯誤之處有很多, 最重要的一點是我們在實例化時
// 不能賦予Person類任何的FirstName參數
// 調用Person的正確位置如下,我們從Student中來調用它
Student.prototype = Object.create(Person.prototype); // See note below
 
// 設置"constructor" 屬性指向Student
Student.prototype.constructor = Student;
 
// 更換"sayHello" 方法
Student.prototype.sayHello = function(){
  console.log("Hello, I'm " + this.firstName + ". I'm studying " + this.subject + ".");
};
 
// 加入"sayGoodBye" 方法
Student.prototype.sayGoodBye = function(){
  console.log("Goodbye!");
};
 
// 測試實例:
var student1 = new Student("Janet", "Applied Physics");
student1.sayHello();   // "Hello, I'm Janet. I'm studying Applied Physics."
student1.walk();       // "I am walking!"
student1.sayGoodBye(); // "Goodbye!"
 
// Check that instanceof works correctly
console.log(student1 instanceof Person);  // true
console.log(student1 instanceof Student); // true

對于 “ Student.prototype = Object.create(Person.prototype); ” 這一行,在不支持  Object.create 方法的老 JavaScript 引擎中,可以使用一個 "polyfill"(又名"shim",查看文章鏈接),或者使用一個 function 來獲得相同的返回值,就像下面:

function createObject(proto) {
    function ctor() { }
    ctor.prototype = proto;
    return new ctor();
}
 
// Usage:
Student.prototype = createObject(Person.prototype);

更多相關信息請參考 Object.create,連接中還有一個老JavaScript引擎的兼容方案(shim)。

封裝

在上一個例子中,Student類雖然不需要知道Person類的walk()方法是如何實現的,但是仍然可以使用這個方法;Student類不需要明確地定義這個方法,除非我們想改變它。 這就叫做封裝,對于所有繼承自父類的方法,只需要在子類中定義那些你想改變的即可。

抽象

抽象是允許模擬工作問題中通用部分的一種機制。這可以通過繼承(具體化)或組合來實現。

JavaScript通過繼承實現具體化,通過讓類的實例是其他對象的屬性值來實現組合。

JavaScript Function 類繼承自Object類(這是典型的具體化) 。Function.prototype的屬性是一個Object實例(這是典型的組合)。

var foo = function(){};
console.log( 'foo is a Function: ' + (foo instanceof Function) );                  // logs "foo is a Function: true"
console.log( 'foo.prototype is an Object: ' + (foo.prototype instanceof Object) ); // logs "foo.prototype is an Object: true"

多態

就像所有定義在原型屬性內部的方法和屬性一樣,不同的類可以定義具有相同名稱的方法;方法是作用于所在的類中。并且這僅在兩個類不是父子關系時成立(繼承鏈中,一個類不是繼承自其他類)。

“javascript是否支持面向對象”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

民乐县| 赞皇县| 浦北县| 黑山县| 福鼎市| 屯留县| 博白县| 新建县| 日喀则市| 永昌县| 岫岩| 彭州市| 汪清县| 邵阳市| 富川| 蚌埠市| 玉屏| 中阳县| 上栗县| 东源县| 澄迈县| 吉首市| 汕尾市| 资阳市| 清远市| 双牌县| 公安县| 攀枝花市| 仁化县| 宽甸| 广安市| 汤阴县| 海安县| 唐山市| 荆州市| 乐清市| 龙陵县| 梁山县| 南江县| 东海县| 弥勒县|