成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

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

yhaolpz / 648人閱讀

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

一、創(chuàng)建對(duì)象

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

最早

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

對(duì)象字面量

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

以上兩種都會(huì)有大量重復(fù)性的代碼,于是乎:

工廠模式

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

雖然解決了重復(fù)代碼問題,但沒有解決對(duì)象識(shí)別(工廠模式無從識(shí)別對(duì)象的類型,因?yàn)槿慷际荗bject,不像Date、Array等,本例中,得到的都是o對(duì)象,對(duì)象的類型都是Object,因此出現(xiàn)了構(gòu)造函數(shù)模式)

構(gòu)造函數(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的實(shí)例,必須用到new

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

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

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

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

構(gòu)造函數(shù)模式內(nèi)的方法每次都會(huì)在實(shí)例上重建一遍,里面的方法在做同一件事,但是實(shí)例化后卻產(chǎn)生了不同的對(duì)象,方法是函數(shù) ,函數(shù)也是對(duì)象。但如果相同的方法都寫在全局作用域里,會(huì)產(chǎn)生很多全局函數(shù),失去了這個(gè)引用類型的封裝性。所以就產(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)建一個(gè)實(shí)例person1
console.log(person1.name);        //lisi

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

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

檢測屬性

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

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

for-in循環(huán)使用時(shí),返回所有能夠通過對(duì)象訪問的可枚舉屬性,實(shí)例和原型的都包括。入所需要取得對(duì)象上所有可枚舉的實(shí)例屬性,推薦Object.key()方法?!旧羁截愑眠^】

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

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

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

原型鏈

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

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

借用構(gòu)造函數(shù)

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

組合繼承

基本思想:使用原型鏈實(shí)現(xiàn)對(duì)原型屬性和方法的繼承,通過借用構(gòu)造函數(shù)來實(shí)現(xiàn)對(duì)實(shí)例屬性的繼承。這樣既通過在原型上定義方法實(shí)現(xiàn)了函數(shù)的復(fù)用,又能夠保證每個(gè)函數(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ù)屬性

有四個(gè)描述特性:

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

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

writable 能否修改屬性值

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

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

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

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

configurable 一樣

enumerable 一樣

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

set 寫入屬性時(shí)調(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

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/103763.html

相關(guān)文章

  • 深入理解JavaScript

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

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

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

    novo 評(píng)論0 收藏0
  • JavaScript深入各種繼承

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

    tomlingtm 評(píng)論0 收藏0
  • 前端面試 - 收藏集 - 掘金

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

    lpjustdoit 評(píng)論0 收藏0
  • 讀《javaScript高級(jí)程序設(shè)計(jì)-第6章》封裝類

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

    seal_de 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<