成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

javaScript抱佛腳之構造函數(shù)、原型等等

yhaolpz / 605人閱讀

摘要:而原型對象都會獲得一個構造函數(shù)屬性,這是一個指向?qū)傩运诤瘮?shù)的指針。所以組合使用構造函數(shù)模式和原型模式簡單來說就是構造函數(shù)里面定義實例屬性,原型模式定義共享屬性。

一、創(chuàng)建對象

創(chuàng)建對象的發(fā)展史:

最早

var person = new Object()
person.name = "Green"

對象字面量

var person = {
    name = "Green",
    age = "25",
    sayName: function(){
        alert("this.name")
    }
}

以上兩種都會有大量重復性的代碼,于是乎:

工廠模式

function createPerson(name, age, job){
    var o = new Object();   // 這個叫做顯式的創(chuàng)造對象
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
        alert("this.name")
    };
    return o;
}
var example = createPerson("Green",25,"無業(yè)!");

雖然解決了重復代碼問題,但沒有解決對象識別(工廠模式無從識別對象的類型,因為全部都是Object,不像Date、Array等,本例中,得到的都是o對象,對象的類型都是Object,因此出現(xiàn)了構造函數(shù)模式)

構造函數(shù)模式

function Person(name,age,family) {
    this.name = name;
    this.age = age;
    this.family = family;
    this.say = function(){
        alert(this.name);
    }
}
var person1 = new Person("lisi",21,["lida","lier","wangwu"]);
var person2 = new Person("lisi",21,["lida","lier","lisi"]);
/* 這是在創(chuàng)建Person的實例,必須用到new

 - 創(chuàng)建一個新對象
 - 將構造函數(shù)的作用域賦過去(this指向新對象)
 - 執(zhí)行構造函數(shù)的代碼
 - 返回新對象 */

console.log(person1 instanceof Object); //true
console.log(person1 instanceof Person); //true

算是構造函數(shù)的特點?
。沒有顯式的創(chuàng)建對象(拗口)
。將屬性方法賦給了this對象
。沒有return

instanceof: 識別對象類型
在全局作用域中調(diào)用一個函數(shù)時,this永遠指向window (踩坑了~)

構造函數(shù)模式內(nèi)的方法每次都會在實例上重建一遍,里面的方法在做同一件事,但是實例化后卻產(chǎn)生了不同的對象,方法是函數(shù) ,函數(shù)也是對象。但如果相同的方法都寫在全局作用域里,會產(chǎn)生很多全局函數(shù),失去了這個引用類型的封裝性。所以就產(chǎn)生了:

原型模式

function Person() {
}

Person.prototype.name = "lisi";
Person.prototype.age = 21;
Person.prototype.family = ["lida","lier","wangwu"];
Person.prototype.say = function(){
    alert(this.name);
};
console.log(Person.prototype);   //Object{name: "lisi", age: 21, family: Array[3]}

var person1 = new Person();        //創(chuàng)建一個實例person1
console.log(person1.name);        //lisi

var person2 = new Person();        //創(chuàng)建實例person2
person2.name = "wangwu";
person2.family = ["lida","lier","lisi"];
console.log(person2);            //Person {name: "wangwu", family: Array[3]}
// console.log(person2.prototype.name);         //報錯
console.log(person2.age);              //21

~ 每個函數(shù)有一個prototype屬性,指向一個對象(該函數(shù)的原型對象),用途是包含了一些屬性和方法等信息,可以被一些由調(diào)用該函數(shù)創(chuàng)建的實例所共享。這些信息不必定義在構造函數(shù)內(nèi),只要添加到原型對象上即可。
~ 而原型對象都會獲得一個constructor(構造函數(shù))屬性,這是一個指向prototype屬性所在函數(shù)的指針。(prototype和constructor屬性在函數(shù)與原型之間互相指)
~ 而創(chuàng)建出的實例內(nèi)部,又有一個指針,指向原型對象(和構造函數(shù)里的prototype指的一樣,其實實例與構造函數(shù)無關,與他的原型有關),是你嗎__proto__?

檢測屬性

使用 hasOwnProperty() 方法可以檢測一個屬性是存在于實例還是他的原型中。給定屬性存在于實例中會返回true。

in操作符:多帶帶使用時,無論屬性存在于哪里,只要有就是true

for-in循環(huán)使用時,返回所有能夠通過對象訪問的可枚舉屬性,實例和原型的都包括。入所需要取得對象上所有可枚舉的實例屬性,推薦Object.key()方法。【深拷貝用過】

原型模式的優(yōu)點是共享,缺點也是共享(過度)。比如兩個實例由調(diào)用同一個構造函數(shù)得來,其中一個實例修改了原型對象上屬性值 ,另一個實例也會共享這個修改。所以:

組合使用構造函數(shù)模式和原型模式

簡單來說就是構造函數(shù)里面定義實例屬性,原型模式定義共享屬性。

原型鏈

簡單描述,就是將一個構造函數(shù)的實例賦值給另一個構造函數(shù)的原型對象。層層套在一起成為一個鏈條。是實現(xiàn)繼承的方法。

原型鏈的繼承仍然存在共享過度的問題,除此之外子類型實例不能給超類型傳遞參數(shù)。于是我們就要用到:

借用構造函數(shù)

基本思想: 在子類型構造函數(shù)內(nèi)部調(diào)用超類型構造函數(shù)(通過call apply方法)
但是這樣方法又必須全定義在構造函數(shù)里,又不能復用了。于是就又有了:

組合繼承

基本思想:使用原型鏈實現(xiàn)對原型屬性和方法的繼承,通過借用構造函數(shù)來實現(xiàn)對實例屬性的繼承。這樣既通過在原型上定義方法實現(xiàn)了函數(shù)的復用,又能夠保證每個函數(shù)都有自己的屬性。

function SuperType(name) {
    this.name = name
    this.color = ["red", "blue"]
}
SuperType.prototype.getName = function() {
    console.log(this.name)
}

function SubType(name, age) {
    SuperType.call(this, name)  // 繼承屬性
    this.age = age
}
SubType.prototype.getAge = function() {
    console.log(this.age)
}

SubType.prototype = new SuperType()  // 繼承方法
SubType.prototype.constructor = SubType

var instance1 = new SubType("zhangsan", 18)
instance1.colors.push("black")
console.log(instance1.colors)  // "red", "blue", "black"
console.log(instance1.getName)  // "zhangsan"
console.log(instance1.getAge)   // 18

var instance2 = new SubType("lisi", 20)
console.log(instance2.colors)   //  "red", "blue"
console.log(instance2.getName)  // "lisi"
console.log(instance2.getAge)  // 20
屬性類型 1、數(shù)據(jù)屬性

有四個描述特性:

configurable 能否刪除屬性 (*置為false后就無法再改變)

enumerable 能否通過for-in循環(huán)返回屬性

writable 能否修改屬性值

value 從這里讀取或者寫入屬性值

前三項默認值都為true,如果需要修改,需要調(diào)用大名鼎鼎的Object.defineProperty()方法

var person = {}
Object.defineProperty(person,"name",{  // 三個參數(shù)
    writable: false,  // 這里如果不指定都默認為false
    value: "Green"
})
alert(person.name);  // Green
person.name = "Blue"
alert(person.name);  // Green
2、訪問器屬性

包含一對getter(讀取訪問器屬性時調(diào)用)和setter(寫入訪問器屬性時調(diào)用)函數(shù)
有四個描述特性:

configurable 一樣

enumerable 一樣

get 讀取屬性時調(diào)用的函數(shù)

set 寫入屬性時調(diào)用的函數(shù)

仍需調(diào)用Object.defineProperty()方法來定義

var book = {
    _year :2004,
    edition: 1
}
Object.defineProperty(book,"year",{
    get: function(){
        return this._year;
    }
    set: function(newValue){
        if(newValue > 2004){
            this._year = newValue;
            this.edition += newValue - 2004;
        }
    }   
})
book.year = 2005
alert(book.edition);  // 2

這是使用訪問器屬性的常見方式,即設置一個屬性的值會導致其他屬性發(fā)生變化。
*_year的下劃線表示只能通過對象方法訪問(不懂,等我再查查)

文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/103763.html

相關文章

  • 深入理解JavaScript

    摘要:深入之繼承的多種方式和優(yōu)缺點深入系列第十五篇,講解各種繼承方式和優(yōu)缺點。對于解釋型語言例如來說,通過詞法分析語法分析語法樹,就可以開始解釋執(zhí)行了。 JavaScript深入之繼承的多種方式和優(yōu)缺點 JavaScript深入系列第十五篇,講解JavaScript各種繼承方式和優(yōu)缺點。 寫在前面 本文講解JavaScript各種繼承方式和優(yōu)缺點。 但是注意: 這篇文章更像是筆記,哎,再讓我...

    myeveryheart 評論0 收藏0
  • 面向?qū)ο蟮?JavaScript

    摘要:是完全的面向?qū)ο笳Z言,它們通過類的形式組織函數(shù)和變量,使之不能脫離對象存在。而在基于原型的面向?qū)ο蠓绞街?,對象則是依靠構造器利用原型構造出來的。 JavaScript 函數(shù)式腳本語言特性以及其看似隨意的編寫風格,導致長期以來人們對這一門語言的誤解,即認為 JavaScript 不是一門面向?qū)ο蟮恼Z言,或者只是部分具備一些面向?qū)ο蟮奶卣?。本文將回歸面向?qū)ο蟊疽?,從對語言感悟的角度闡述為什...

    novo 評論0 收藏0
  • JavaScript深入各種繼承

    摘要:通常有這兩種繼承方式接口繼承和實現(xiàn)繼承。理解繼承的工作是通過調(diào)用函數(shù)實現(xiàn)的,所以是寄生,將繼承工作寄托給別人做,自己只是做增強工作。適用基于某個對象或某些信息來創(chuàng)建對象,而不考慮自定義類型和構造函數(shù)。 一、繼承的概念 繼承,是面向?qū)ο笳Z言的一個重要概念。通常有這兩種繼承方式:接口繼承和實現(xiàn)繼承。接口繼承只繼承方法簽名,而實現(xiàn)繼承則繼承實際的方法。 《JS高程》里提到:由于函數(shù)沒有簽名,...

    tomlingtm 評論0 收藏0
  • 前端面試 - 收藏集 - 掘金

    摘要:一基礎接口的意義百度規(guī)范擴展回調(diào)抽象類的意義我的前端面試經(jīng)歷百度前端掘金博主就讀于電子科技大學,大三狗一枚面試是個漫長的過程,從海投到收獲電話面試,一面二面三面,一個步驟出錯那么后面就宣告終結。 一道常被人輕視的前端 JS 面試題 - 前端 - 掘金 目錄前言第一問第二問變量聲明提升函數(shù)表達式第三問第四問第五問第六問構造函數(shù)的返回值第七問最后前言 年前剛剛離職了,分享下我曾經(jīng)出過的一道...

    lpjustdoit 評論0 收藏0
  • 讀《javaScript高級程序設計-第6章》封裝類

    摘要:創(chuàng)建構造函數(shù)后,其原型對象默認只會取得屬性至于其他的方法都是從繼承來的。上圖展示了構造函數(shù)的原型對象和現(xiàn)有的兩個實例之間的關系。所有原生的引用類型都在其構造函數(shù)的原型上定義了方法。 第6章我一共寫了3篇總結,下面是相關鏈接:讀《javaScript高級程序設計-第6章》之理解對象讀《javaScript高級程序設計-第6章》之繼承 工廠模式 所謂的工廠模式就是,把創(chuàng)建具體對象的過程抽象...

    seal_de 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<