您好,登錄后才能下訂單哦!
這篇文章主要介紹“javascript的面向對象特性是什么”,在日常操作中,相信很多人在javascript的面向對象特性是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”javascript的面向對象特性是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
面向對象的三大基本特性
封裝(把相關的信息(無論數據或方法)存儲在對象中的能力)
繼承(由另一個類(或多個類)得來類的屬性和方法的能力)
多態(一個對象在不同情況下的多種形態)
定義類或對象
第一種:基于Object對象
var person = new Object(); person.name = "Rose"; person.age = 18; person.getName = function () { return this.name; }; console.log(person.name);//Rose console.log(person.getName);//function () {return this.name;} console.log(person.getName());//Rose
缺點:不能創建多個對象。
第二種:基于字面量方式
var person = { name : "Rose", age : 18 , getName : function () { return this.name; } }; console.log(person.name);//Rose console.log(person.getName);//function () {return this.name;} console.log(person.getName());//Rose
優點:比較清楚的查找對象包含的屬性和方法;
缺點:不能創建多個對象。
第三種:工廠模式
方式一:
function createPerson(name,age) { var object = new Object(); object.name = name; object.age = age; object.getName = function () { return this.name; }; return object; } var person1 = createPerson("Rose",18); var person2 = createPerson("Jack",20); console.log(person1.name);//Rose console.log(person2.name);//Jack console.log(person1.getName === person2.getName);//false//重復生成函數,為每個對象都創建獨立的函數版本
優點:可以創建多個對象;
缺點:重復生成函數getName(),為每個對象都創建獨立的函數版本。
方式二:
function createPerson(name,age) { var object = new Object(); object.name = name; object.age = age; object.getName = getName; return object; } function getName() { return this.name; } var person1 = createPerson("Rose",18); var person2 = createPerson("Jack",20); console.log(person1.name);//Rose console.log(person2.name);//Jack console.log(person1.getName === person2.getName);//true//共享同一個函數
優點:可以創建多個對象;
缺點:從語義上講,函數getName()不太像是Person對象的方法,辨識度不高。
第四種:構造函數方式
方式一:
function Person(name,age) { this.name = name; this.age = age; this.getName = function () { return this.name; } } var person1 = new Person("Rose",18); var person2 = new Person("Jack",20); console.log(person1.name);//Rose console.log(person2.name);//Jack console.log(person1.getName === person2.getName); //false//重復生成函數,為每個對象都創建獨立的函數版本
優點:可以創建多個對象;
缺點:重復生成函數getName(),為每個對象都創建獨立的函數版本。
方式二:
function Person(name,age) { this.name = name; this.age = age; this.getName = getName ; } function getName() { return this.name; } var person1 = new Person("Rose",18); var person2 = new Person("Jack",20); console.log(person1.name);//Rose console.log(person2.name);//Jack console.log(person1.getName === person2.getName); //true//共享同一個函數
優點:可以創建多個對象;
缺點:從語義上講,函數getName()不太像是Person對象的方法,辨識度不高。
第五種:原型方式
function Person() { } Person.prototype.name = 'Rose'; Person.prototype.age = 18; Person.prototype.getName = function () { return this.name; }; var person1 = new Person(); var person2 = new Person(); console.log(person1.name);//Rose console.log(person2.name);//Rose//共享同一個屬性 console.log(person1.getName === person2.getName);//true//共享同一個函數
缺點:它省略了為構造函數傳遞初始化參數,這在一定程序帶來不便;另外,最主要是當對象的屬性是引用類型時,它的值是不變的,總是引用同一個外部對象,所有實例對該對象的操作都會影響其它實例:
function Person() { } Person.prototype.name = 'Rose'; Person.prototype.age = 18; Person.prototype.lessons = ["語文","數學"]; Person.prototype.getName = function () { return this.name; }; var person1 = new Person(); person1.lessons.push("英語"); var person2 = new Person(); console.log(person1.lessons);//["語文", "數學", "英語"] console.log(person2.lessons);//["語文", "數學", "英語"]//person1修改影響了person2
第六種:構造函數+原型方式(推薦)
function Person(name,age) { this.name = name; this.age = age; } Person.prototype.getName = function () { return this.name; }; var person1 = new Person('Rose', 18); var person2 = new Person('Jack', 20); console.log(person1.name);//Rose console.log(person2.name);//Jack console.log(person1.getName === person2.getName);//true//共享原型中定義的方法
缺點:屬性定義在構造函數內,方法定義在構造函數外,與面向對象的封裝思想不符。
第七種:構造函數+動態原型方式(推薦)
方式一:
function Person(name,age) { this.name = name; this.age = age; if (typeof Person._getName === "undefined"){ Person.prototype.getName = function () { return this.name; }; Person._getName = true; } } var person1 = new Person('Rose', 18); var person2 = new Person('Jack', 20); console.log(person1.name);//Rose console.log(person2.name);//Jack console.log(person1.getName === person2.getName);//true//共享原型中定義的方法
方式二:
function Person(name,age) { this.name = name; this.age = age; if (typeof this.getName !== "function"){ Person.prototype.getName = function () { return this.name; }; } } var person1 = new Person('Rose', 18); var person2 = new Person('Jack', 20); console.log(person1.name);//Rose console.log(person2.name);//Jack console.log(person1.getName === person2.getName);//true//共享原型中定義的方法
對象屬性的擴展及刪除
Javascript的對象可以使用 '.' 操作符動態的擴展其屬性,可以使用 'delete' 關鍵字或將屬性的值設置為 'undefined' 來刪除屬性。
function Person(name,age) { this.name = name; this.age = age; if (typeof Person._getName === "undefined"){ Person.prototype.getName = function () { return this.name; }; Person._getName = true; } } var person = new Person("Rose",18); person.job = 'Engineer';//添加屬性 console.log(person.job);//Engineer delete person.job;//刪除屬性 console.log(person.job);//undefined//刪除屬性后值為undefined person.age = undefined;//刪除屬性 console.log(person.age);//undefined//刪除屬性后值為undefined
對象屬性類型
數據屬性
特性:
[configurable]:表示能否使用delete操作符刪除從而重新定義,或能否修改為訪問器屬性。默認為true;
[enumberable]:表示是否可通過for-in循環返回屬性。默認true;
[writable]:表示是否可修改屬性的值。默認true;
[value]:包含該屬性的數據值。讀取/寫入都是該值。默認為undefined;如上面實例對象person中定義了name屬性,其值為'My name',對該值的修改都反正在這個位置
function Person(name,age) { this.name = name; this.age = age; if (typeof Person._getName === "undefined"){ Person.prototype.getName = function () { return this.name; }; Person._getName = true; } } var person = new Person("Rose",18); Object.defineProperty(person,"name",{configurable:false,writable:false}); person.name = "Jack"; console.log(person.name);//Rose//重新賦值無效 delete person.name; console.log(person.name);//Rose//刪除無效
注意:
一旦將configurable設置為false,則無法再使用defineProperty將其修改為true(執行會報錯:cannot redefine property : propertyName)
function Person(name,age) { this.name = name; this.age = age; if (typeof Person._getName === "undefined"){ Person.prototype.getName = function () { return this.name; }; Person._getName = true; } } var person = new Person("Rose",18); Object.defineProperty(person,"name",{configurable:false,writable:false}); person.name = "Jack"; console.log(person.name);//Rose//重新賦值無效 delete person.name; console.log(person.name);//Rose//刪除無效 Object.defineProperty(person,"name",{configurable:true,writable:true});//Cannot redefine property: name
訪問器屬性
特性:
[configurable]:是否可通過delete操作符刪除重新定義屬性;
[numberable]:是否可通過for-in循環查找該屬性;
[get]:讀取屬性時調用,默認:undefined;
[set]:寫入屬性時調用,默認:undefined;
訪問器屬性不能直接定義,必須使用defineProperty()或defineProperties來定義:如下
function Person(name,age) { this.name = name; this._age = age; if (typeof Person._getName === "undefined"){ Person.prototype.getName = function () { return this.name; }; Person._getName = true; } } var person = new Person("Rose",18); Object.defineProperty(person,"age",{ get:function () { return this._age; }, set:function (age) { this._age = age; }}); person.age = 20; console.log(person.age);//20//person.age=20是使用set方法將20賦值給_age,person.age是使用get方法將_age的讀取出來 console.log(person._age);//20
獲取所有的屬性和屬性的特性
使用Object.getOwnPropertyNames(object)方法可以獲取所有的屬性;
使用Object.getOwnPropertyDescriptor(object,property)方法可以取得給定屬性的特性;
function Person(name,age) { this.name = name; this._age = age; if (typeof Person._getName === "undefined"){ Person.prototype.getName = function () { return this.name; }; Person._getName = true; } } var person = new Person("Rose",18); Object.defineProperty(person,"age",{ get:function () { return this._age; }, set:function (age) { this._age = age; }}); console.log(Object.getOwnPropertyNames(person));//["name", "_age", "age"] console.log(Object.getOwnPropertyDescriptor(person,"age"));//{enumerable: false, configurable: false, get: function, set: function}
對于數據屬性,可以取得:configurable,enumberable,writable和value;
對于訪問器屬性,可以取得:configurable,enumberable,get和set;
繼承機制實現
對象冒充
function Father(name) { this.name = name ; this.getName = function () { return this.name; } } function Son(name,age) { this._newMethod = Father; this._newMethod(name); delete this._newMethod; this.age = age; this.getAge = function () { return this.age; } } var father = new Father("Tom"); var son = new Son("Jack",18); console.log(father.getName());//Tom console.log(son.getName());//Jack//繼承父類getName()方法 console.log(son.getAge());//18
多繼承(利用對象冒充可以實現多繼承)
function FatherA(name) { this.name = name ; this.getName = function () { return this.name; } } function FatherB(job) { this.job = job; this.getJob = function () { return this.job; } } function Son(name,job,age) { this._newMethod = FatherA; this._newMethod(name); delete this._newMethod; this._newMethod = FatherB; this._newMethod(job); delete this._newMethod; this.age = age; this.getAge = function () { return this.age; } } var fatherA = new FatherA("Tom"); var fatherB = new FatherB("Engineer"); var son = new Son("Jack","Programmer",18); console.log(fatherA.getName());//Tom console.log(fatherB.getJob());//Engineer console.log(son.getName());//Jack//繼承父類FatherA的getName()方法 console.log(son.getJob());//Programmer//繼承父類FatherB的getJob()方法 console.log(son.getAge());//18
call()方法
function Father(name) { this.name = name ; this.getName = function () { return this.name; } } function Son(name,job,age) { Father.call(this,name); this.age = age; this.getAge = function () { return this.age; } } var father = new Father("Tom"); var son = new Son("Jack","Programmer",18); console.log(father.getName());//Tom console.log(son.getName());//Jack//繼承父類getName()方法 console.log(son.getAge());//18
多繼承(利用call()方法實現多繼承)
function FatherA(name) { this.name = name ; this.getName = function () { return this.name; } } function FatherB(job) { this.job = job; this.getJob = function () { return this.job; } } function Son(name,job,age) { FatherA.call(this,name); FatherB.call(this,job); this.age = age; this.getAge = function () { return this.age; } } var fatherA = new FatherA("Tom"); var fatherB = new FatherB("Engineer"); var son = new Son("Jack","Programmer",18); console.log(fatherA.getName());//Tom console.log(fatherB.getJob());//Engineer console.log(son.getName());//Jack//繼承父類FatherA的getName()方法 console.log(son.getJob());//Programmer//繼承父類FatherB的getJob()方法 console.log(son.getAge());//18
apply()方法
function Father(name) { this.name = name ; this.getName = function () { return this.name; } } function Son(name,job,age) { Father.apply(this,new Array(name)); this.age = age; this.getAge = function () { return this.age; } } var father = new Father("Tom"); var son = new Son("Jack","Programmer",18); console.log(father.getName());//Tom console.log(son.getName());//Jack//繼承父類getName()方法 console.log(son.getAge());//18
多繼承(利用apply()方法實現多繼承)
function FatherA(name) { this.name = name ; this.getName = function () { return this.name; } } function FatherB(job) { this.job = job; this.getJob = function () { return this.job; } } function Son(name,job,age) { FatherA.apply(this,new Array(name)); FatherB.apply(this,new Array(job)); this.age = age; this.getAge = function () { return this.age; } } var fatherA = new FatherA("Tom"); var fatherB = new FatherB("Engineer"); var son = new Son("Jack","Programmer",18); console.log(fatherA.getName());//Tom console.log(fatherB.getJob());//Engineer console.log(son.getName());//Jack//繼承父類FatherA的getName()方法 console.log(son.getJob());//Programmer//繼承父類FatherB的getJob()方法 console.log(son.getAge());//18
原型鏈方法
function Father() { } Father.prototype.name = "Tom"; Father.prototype.getName = function () { return this.name; }; function Son() { } Son.prototype = new Father(); Son.prototype.age = 18; Son.prototype.getAge = function () { return this.age; }; var father = new Father(); var son = new Son(); console.log(father.getName());//Tom console.log(son.getName());//Tom//繼承父類FatherA的getName()方法 console.log(son.getAge());//18
混合方式(call()+原型鏈)
function Father(name) { this.name = name; } Father.prototype.getName = function () { return this.name; }; function Son(name,age) { Father.call(this,name); this.age = age; } Son.prototype = new Father(); Son.prototype.getAge = function () { return this.age; }; var father = new Father("Tom"); var son = new Son("Jack",18); console.log(father.getName());//Tom console.log(son.getName());//Jack//繼承父類Father的getName()方法 console.log(son.getAge());//18
多態機制實現
function Person(name) { this.name = name; if (typeof this.getName !== "function"){ Person.prototype.getName = function () { return this.name; } } if (typeof this.toEat !== "function"){ Person.prototype.toEat = function (animal) { console.log( this.getName() + "說去吃飯:"); animal.eat(); } } } function Animal(name) { this.name = name; if (typeof this.getName !== "function"){ Animal.prototype.getName = function () { return this.name; } } } function Cat(name) { Animal.call(this,name); if (typeof this.eat !== "function"){ Cat.prototype.eat = function () { console.log(this.getName() + "吃魚"); } } } Cat.prototype = new Animal(); function Dog(name) { Animal.call(this,name); if (typeof this.eat !== "function"){ Dog.prototype.eat = function () { console.log(this.getName() + "啃骨頭"); } } } Dog.prototype = new Animal(); var person = new Person("Tom"); person.toEat(new Cat("cat"));//Tom說去吃飯:cat吃魚 person.toEat(new Dog("dog"));//Tom說去吃飯:dog啃骨頭
到此,關于“javascript的面向對象特性是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。