javaScript 面向物件--封裝和prototype屬性
一般面向物件的語言都具有三大特徵,封裝、繼承,多型,例如像java 和c++。但是javaScript它可以說不是完全的面向物件的語言,因為它沒有類的概念,但是它又是面向物件的,因為它可以封裝屬性和方法,並且也可以實現繼承。
1、字面量模式
字面量的模式來建立一個物件
var person = {
name : 'wzj',
age : 25
}
console.log(person.name);// wzj
console.log(typeof person);//Object
但是這種方式比較麻煩,如果生成多個例項,寫起來比較繁瑣。
2、通過函式模式
可以通過函式來解決上面程式碼重複的問題
function person(name, age){
var person = new Object();
person.name = name;
person.age = age;
return person;
}
var person1 = person('wzj',25);//會返回一個物件
var person2 = person('dxy',22);//也會返回一個物件
console.log(person.name);//wzj
可以看出二者並沒有必然的聯絡,不能反映他們是同一個 person 創建出來的。
我們通過控制檯可以看到,這兩個物件不僅具有age和name屬性還有一個 proto
3、通過建構函式封裝屬性和方法
建構函式的概念我們並不陌生,在java中建構函式是用來實現物件屬性的初始化的,並且建構函式也可以實現過載。但是在javaScript中的建構函式和一般的函式沒有多大區別。
javaScript中的建構函式大致具有以下特徵:
- 建構函式就是一個普通的函式,但是首字母要大寫例如
Person(name, age)
。 - 建構函式內部具有
this
,變數,並且this會繫結在例項物件上。 - 建構函式需要通過
new
關鍵字來例項化物件,並且通過new
關鍵字建立的物件都具有constructor屬性。
function Person(name, age){
this.name = name;
this.age = age;
this.sayName = function () {
console.log(this.name);
}
}
var person1 = new Person('wzj',25);
var person2 = new Person('dxy',23);
//二者指向同一個建構函式,返回true
console.log(person1.constructor == person2.constructor);
//可以判斷出例項物件和原型物件之間的關係,返回true
console.log(person1 instanceof Person);
通過建構函式的方法建立物件不僅消除那種字面量冗餘的問題,也解決了原型物件和例項物件之間的關聯問題,但是建構函式也具有一些問題,例如方法和屬性的共有部分如何抽取問題,在java中我們可以宣告介面來實現共有方法的抽取,那麼在javaScript中我們如何實現呢?
4、建構函式的一些問題
首先來看一個示例:
function Car(name, color){
this.name = name;
this.color = color;
this.sayName = function () {
console.log(this.name);
}
this.material = '金屬';
this.start = function () {
console.log("啟動引擎!")
}
}
var car1 = new Car('梅賽德斯',"黑色");
var car2 = new Car('凱迪拉克','白色');
//這個方法每個物件都具有
car1.start();
car2.start();
//返回false,因為所有的例項的這個方法 都是存在一個自己獨立的地址中
console.log(car1.start == car2.start);
然後在看下控制檯
可以看到兩個物件有公共的部分,這種方式造成了記憶體的浪費,因為這兩個對像所共有的方法,是在各自的記憶體中存放著,並不是存在公共的區域,那麼我們能不能實現java中樣把這種共有的方法,宣告為static的放在類載入區呢,很顯然不能,因為javaScript沒有類的概念的。
並且,瀏覽沒有類載入區的概念,所以我們不能借鑑。但是並不是說不能實現那種方式。
javaScript規定 每個建構函式都預設具有prototype
屬性,並且這個屬性指向一個物件,這個被指向的物件的所有屬性和方法都將被次建構函式所繼承。
function Car2(name, color){
this.name = name;
this.color = color;
this.sayName = function () {
console.log(this.name);
}
}
//通過 prototype 來實現共有方法的抽取,並且實現了物件方法的繼承
Car2.prototype.start = function () {
console.log("引擎啟動!")
}
Car2.prototype.material = '金屬';
/**
1. 此時所有的例項的start方法和material屬性,其實都指向同一個記憶體地址,即 指向prototype物件.
2. @type {Car2}
*/
var car1 = new Car2('梅賽德斯','黑色');
var car2 = new Car2('凱迪拉克','白色');
car1.start();
car2.start();
console.log(car1.start == car2.start);//返回true,因為所有例項的方法都指向同一個地址
通過控制檯可以發現,car1和car2自身並沒有start()
方法和material
屬性,但是可以呼叫start方法。
通過原型鏈可以看到,start()方法和material屬性
存在。因此可以通過建構函式的prototype屬性來實現方法和屬性的共有和擴充套件。
5、驗證prototype的一般方法
- 1、
isPrototypeOf()
: 用來判斷,某個prototype物件和某個例項之間的關係. - 2、
hasOwnPrototype()
: 用來判斷,某個屬性是例項自身的屬性還是繼承自Prototype物件的屬性. - 3、
in
: 用來判斷某個例項是否含有某個屬性,不管是否是自身屬性,還可以用來遍歷某個物件的 所有屬性。
這些方法是繼承自Object()物件.
console.log(Car2.prototype.isPrototypeOf(car1));//true
console.log(car1.hasOwnProperty('start'));//false start是 prototype物件的屬性
console.log(car1.hasOwnProperty('name')); //true name是car1自身的屬性
console.log('start' in car1);//true
console.log('name' in car1); //true
console.log('age' in car1); //false
console.log('-------------------------\n')
for (var prop in car1){
console.log("car1["+prop+"] = "+car1[prop]);
}
控制檯列印結果
5、prototype的使用
知道了prototype的作用,name應該怎麼使用它呢?如果通過原型新增得方法和物件自身所具有的方法和屬性重複了,會優先呼叫哪一個方法?
function Car2(name, color){
this.name = name;
this.color = color;
this.sayName = function () {
console.log(this.name);
}
}
//通過 prototype 來實現共有方法的抽取,並且實現了物件方法的繼承
Car2.prototype.start = function () {
console.log("引擎啟動!")
}
Car2.prototype.material = '金屬';
Car2.prototype.name = "default";
Car2.prototype.sayName = function () {
console.log(this.name+"覆蓋建構函式中已經具有的方法!")
}
var car = new Car2('梅賽德斯','黑色');
car.sayName();//列印梅賽德斯
console.log(car.name);//列印梅賽德斯
console.log(car.material);//列印黑色
通過控制檯可以發現,物件本身所具有的的方法,並沒有被通過建構函式建立的方法所覆蓋
得出以下結論
當物件本身的屬性或方法與原型的屬性和方法同名的時候
- 預設呼叫的物件自身的屬性和方法
- 通過原型增加的屬性和方法是確實存在的
- 函式本身的屬性和方法要優先於原型的屬性和方法
當通過delete方法刪除物件中的方法的時候不會刪除建構函式中的.
var car = new Car2('梅賽德斯','黑色');
Car2.prototype.name = "default";
Car2.prototype.sayName = function () {
console.log(this.name+"覆蓋建構函式中已經具有的方法!")
}
//刪除物件car 中的方法sayName(),此時物件本身並不具有這個方法
delete (car.sayName);
car.sayName();//列印default覆蓋建構函式中已經具有的方法!
console.log(car.name);//列印default
console.log(car.material);//列印黑色
相關推薦
javaScript 面向物件--封裝和prototype屬性
一般面向物件的語言都具有三大特徵,封裝、繼承,多型,例如像java 和c++。但是javaScript它可以說不是完全的面向物件的語言,因為它沒有類的概念,但是它又是面向物件的,因為它可以封裝屬性和方法,並且也可以實現繼承。 1、字面量模式 字面量的模式
Java面向物件封裝和繼承
面向物件 什麼是面向過程、面向物件? 面向過程與面向物件都是我們程式設計中,編寫程式的一種思維方式。 面向過程的程式設計方式,是遇到一件事時,思考“我該怎麼做”,然後一步步實現的過程。例如:公司打掃衛生(擦玻璃、掃地、拖地、倒垃圾等),按照面向過程的程式設計方式會思考“打掃衛生我該怎麼做,然後一件件的完
javascript面向物件程式設計--設計超類和子類,設計元類
在javascript中,Object物件是通用類,其他所有內建物件和自定義構造物件都是專用類,即Object物件是超類,其他內建物件和自定義物件都是Object的子類,所有在javascript語言中,所有的物件都繼承Object定義的屬性和方法 Object.prototype.name='
JavaScript 面向物件之二 —— 函式上下文(call() 和 apply())
本系列文章根據《愛前端邵山歡老師深入淺出的js面向物件》視訊整理歸納 call() 和 apply() 這兩個都是函式的方法,只有函式能夠通過點方法呼叫call()、apply(),表示用指定的上下文執行這個函式。 如下,定義一個函式 fun,當 fun 函式裡
JavaScript面向物件程式設計-封裝
前言 面向物件程式設計是將需求抽象成一個物件,針對物件分析其特徵(屬性)和動作(方法)。這個物件我們稱之為類。面向物件程式設計思想其中一個特點就是封裝,就是把需要的功能放在一個物件裡。但是JavaScript這種解釋性的弱型別語言沒有經典強型別語言中通過關鍵字cla
javascript面向物件程式設計--繼承--類繼承2(封裝類繼承模式)
function extend(Sub,Sup){ var F=function(){}; F.prototype=Sup.prototype; Sub.prototype=new F(); Sub.prototype.constructor=Sub
javascript面向物件程式設計---封裝--被動封裝+主動封裝
封裝:把物件內部的資料和操作細節進行隱藏,javascript不支援封裝操作,但可以使用閉包函式來模擬型別封裝 被動封裝:對物件內部資料進行適當約定,這種約定並沒有強制性,它主要針對公共物件而言 var Card=function(name,sex,work,detail
Javascript 面向物件程式設計(一):封裝
Javascript是一種基於物件(object-based)的語言,你遇到的所有東西幾乎都是物件。但是,它又不是一種真正的面向物件程式設計(OOP)語言,因為它的語法中沒有class(類)。 那麼,如果我們要把"屬性"(property)和"方法"(method),封裝成
Javascript 面向物件程式設計封裝問題
//建構函式模式相對於工廠模式來說,比較省記憶體。 //下面的方法是建構函式模式加上原型模式實現,建構函式模式雖說比工廠模式省記憶體, //但是還是存在浪費記憶體的現象。 function Person(name,age,job){ this.name=name;
javascript面向物件系列第一篇——建構函式和原型物件
前面的話 一般地,javascript使用建構函式和原型物件來進行面向物件程式設計,它們的表現與其他面向物件程式語言中的類相似又不同。本文將詳細介紹如何用建構函式和原型物件來建立物件 建構函式 建構函式是用new建立物件時呼叫的函式,與普通唯一的區別是建構函式名應該首字母大寫 func
讀《JavaScript 面向物件精要》和《JavaScript 啟示錄》精華總結
導讀:本文詳細總結了JavaScript 面向物件基礎的知識點,主要來自《JavaScript 面向物件精要》《JavaScript 啟示錄》這兩本書,推薦給各位做做開發的朋友。 目錄 引子: 最近看了兩本書,書中有些內容對自己還是很新的
Python.面向物件---類和物件屬性的增刪改查
一,類屬性的操作class Chinese: country = 'China' def __init__(self,name): self.name = name def play_ball(self,ball): p
自學Python day6--------面向物件程式設計(例項屬性和類屬性)
因為Python是動態語言,可以根據例項任意繫結屬性,如: class Student(object): def __init__(self, name): self.name = name s = Student('Bob') s.
JavaScript(面向物件+原型理解+繼承+作用域鏈和閉包+this使用總結)
JavaScript(面向物件+原型理解+繼承+作用域鏈和閉包+this使用總結) 一、面向物件 1、什麼是面向物件 ☞ 面向物件就是把構成問題事物分解成多個物件,建立物件不是為了
javascript 面向物件(屬性型別)-筆記
屬性型別: 屬性在建立時都帶一些特徵值,javascript通過這些特殊值定義他們行為,javascript中有兩種屬性:資料屬性, 訪問器屬性 1.資料屬性 資料屬性包含一個數據的值的位置。在這個位
黑馬程式設計師--Java學習日記之面向物件(封裝,繼承和構造方法)
------- android培訓、java培訓、期待與您交流! ---------- 面向物件思想: 面向過程,以函式為基礎,關注的是實現過程; 面向物件,以物件為基礎,關注的是最終結果; 面向物件思想特點 是一種更符合我們思想習慣的思想
Python 進階_OOP 面向物件程式設計_類屬性和方法
目錄 類屬性 在理解類屬性之前要先搞清楚 例項屬性 和 函式屬性 之間的區別: 1. 例項屬性:指的是例項化類物件的屬性,需要在類中使用 self 關鍵字來將其和例項化物件繫結的屬性。 2. 函式屬性:指的是定義在函式體內的屬性,其可以是例項屬
javascript 面向物件學習(三)——this,bind、apply 和 call
this 是 js 裡繞不開的話題,也是非常容易混淆的概念,今天試著把它理一理。 this 在非嚴格模式下,總是指向一個物件,在嚴格模式下可以是任意值,本文僅考慮非嚴格模式。記住它總是指向一個物件對於理解它的意義很重要。this 在實際使用中,大致分為以下幾種情況: 1. 函式作為物件的方法呼叫時,this
javascript面向對象和原型————呱呱二號
無法訪問 原型模式 冒充 判斷 傳遞 pre asp clas 相等 面向對象 1、工廠模式 function createObject(name,age){ let obj = new Object(); this.name = name; this.age
javascript 面向對象和繼承
color asc asdasdas java 代碼 round == ima 個人 我相信,當你讀完這篇100%原創文章時,javascript 面向對象和繼承輕松拿下不再是問題。 統一的html和css <div id="app"></