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

資訊專欄INFORMATION COLUMN

[學(xué)習(xí)筆記](méi) JavaScript 原型

beita / 777人閱讀

今天研究了一下js的原型,把自己的理解寫到這里,如有不正確的地方,還望指出,在此先謝過(guò)啦~

什么是原型?

原型是一個(gè)對(duì)象。所有對(duì)象都有原型。任何一個(gè)對(duì)象也都可以成為其他對(duì)象的原型。
每個(gè)原型都有一個(gè) constructor 屬性指向其構(gòu)造函數(shù)。

怎么訪問(wèn)原型?

一個(gè)對(duì)象的原型被對(duì)象內(nèi)部的 [[Prototype]] 屬性所持有。
一句話就是,所有對(duì)象都有原型,其原型是該對(duì)象的內(nèi)部屬性。那么有哪些方法可以訪問(wèn)到這個(gè)內(nèi)部屬性呢?

ECMAScript 5 增加了方法 Object.getPrototypeOf() ,用于返回對(duì)象 [[Prototype]] 的值。IE 9+、Firefox 3.5+、Safari 5+、Opera 12+ 和 Chrome 都實(shí)現(xiàn)了該方法。

除了IE,其他瀏覽器都支持非標(biāo)準(zhǔn)的訪問(wèn)器 __proto__

如果這兩者都不起作用,我們就需要通過(guò)對(duì)象的構(gòu)造函數(shù)找它的原型屬性了。

var a = {};
Object.getPrototypeOf(a);
a.__proto__;
a.constructor.prototype;
函數(shù)的 prototype 屬性

不知親剛剛有沒(méi)有注意到訪問(wèn) [[Prototype]] 的最后一個(gè)方法 a.constructor.prototype; ,直接使用了構(gòu)造函數(shù)的 prototype屬性。

在這里要多說(shuō)兩句,js中函數(shù)也是對(duì)象,所以函數(shù)也有原型,其原型也和其他對(duì)象一樣,可以通過(guò) Object.getPrototypeOf()__proto__ 訪問(wèn)。但是創(chuàng)建對(duì)象時(shí),我們往往要使用構(gòu)造函數(shù) (constructor) 的原型,為了用起來(lái)方便,就給構(gòu)造函數(shù)添加了 prototype 屬性,用于直接訪問(wèn)其原型。由于所有的函數(shù)都可以成為構(gòu)造函數(shù),所以就造就了函數(shù)有那么一點(diǎn)點(diǎn)特(you)殊(shi)—— 一個(gè)函數(shù)可以通過(guò)其 prototype 屬性直接訪問(wèn)其原型,或者說(shuō) 一個(gè)函數(shù)的 prototype 屬性指向其原型對(duì)象。

如果僅僅只是因?yàn)橐粋€(gè)實(shí)例而使用原型是沒(méi)有多大意義的,這和直接添加屬性到這個(gè)實(shí)例是一樣的。原型真正魅力體現(xiàn)在多個(gè)實(shí)例共用一個(gè)原型,原型對(duì)象的屬性一旦定義,就可以被多個(gè)引用它的實(shí)例所繼承,這種操作在性能和維護(hù)方面其意義是不言自明的。

這也是構(gòu)造函數(shù)存在的原因,構(gòu)造函數(shù)提供了一種方便的跨瀏覽器機(jī)制,這種機(jī)制允許在創(chuàng)建實(shí)例時(shí)為實(shí)例提供一個(gè)通用的原型。

原型語(yǔ)法

在使用原型前,先寫一下構(gòu)造函數(shù)部分。

function Calculator (decimalDigits, tax) {
    this.decimalDigits = decimalDigits;
    this.tax = tax;
};
分步聲明

分開設(shè)置原型的每個(gè)屬性。

Calculator.prototype.add = function (x, y) {
    return x + y;
};

Calculator.prototype.subtract = function (x, y) {
    return x - y;
};

這樣,在new Calculator對(duì)象以后,就可以調(diào)用add方法來(lái)計(jì)算結(jié)果了。
此時(shí), Calculator.prototypeconstructor 屬性指向 Calculator。即:
Calculator.prototype.constructor = Calculator

更簡(jiǎn)單的原型語(yǔ)法

通過(guò)給Calculator的prototype屬性賦值對(duì)象字面量來(lái)設(shè)定Calculator對(duì)象的原型。

Calculator.prototype = {
    add: function (x, y) {
        return x + y;
    },

    subtract: function (x, y) {
        return x - y;
    }
};

上面的代碼中,將 Calculator.prototype 賦值為一個(gè)以對(duì)象字面量形式創(chuàng)建的新對(duì)象。最終結(jié)果相同,但是,此時(shí) constructor 屬性不再指向 Calculator ,即 Calculator.prototype.constructor != Calculator 。

每創(chuàng)建一個(gè)函數(shù),就會(huì)同時(shí)創(chuàng)建它的 prototype 對(duì)象,這個(gè)對(duì)象會(huì)自動(dòng)獲得 constructor 屬性。而我們這里使用的語(yǔ)法,本質(zhì)上完全重寫了默認(rèn)的 prototype 對(duì)象,因此 constructor 屬性也就變成了新對(duì)象的 constructor 屬性 —— 指向 Object 構(gòu)造函數(shù)。

如果 constructor 的值很重要,可以向下面一樣設(shè)定:

Calculator.prototype = {

    constructor: Calculator, // 修復(fù)constructor 屬性

    add: function (x, y) {
        return x + y;
    },

    subtract: function (x, y) {
        return x - y;
    }
};
其他方式

使用function立即執(zhí)行的表達(dá)式來(lái)為prototype賦值,格式如下:

Calculator.prototype = function () {
    var add = function (x, y) {
        return x + y;
    },

    var subtract = function (x, y) {
        return x - y;
    }

    return {
        add: add,
        subtract: subtract
    }
} ();
原型的動(dòng)態(tài)性
var friend = new Person();

Person.prototype.sayHi = function () {
    alert("hi");
};

friend.sayHi(); // "hi" (沒(méi)有問(wèn)題)

在以上代碼中,即使 friend 是在添加新方法之前創(chuàng)建的,但它仍然可以訪問(wèn)這個(gè)新方法。其原因可以歸結(jié)為實(shí)例與原型之間的松散連接關(guān)系。當(dāng)我們調(diào)用 friend.sayHi() 時(shí),會(huì)首先在實(shí)例中搜索名為 sayHi 的屬性,在沒(méi)有找到的情況下,會(huì)繼續(xù)搜索原型。因?yàn)閷?shí)例實(shí)例與原型之間連接是一個(gè)指針,而非副本,因此可以在原型中找到新的 sayHi 屬性并返回保存在那里的函數(shù)。

可以隨時(shí)為原型添加屬性和方法,并且修改能立即在所有對(duì)象實(shí)例中反映出來(lái),但如果重寫了原型對(duì)象,那結(jié)果就不一樣了……

function Person () {
}

var friend = new Person();

Person.prototype = {
    constructor: Person,
    name: "Nicholas",
    age: 29,
    job: "software Engineer",
    sayHi: function () {
        alert("hi");
    }
};

friend.sayHi(); // error

在這個(gè)例子中,先創(chuàng)建了 friend 實(shí)例,然后又重寫其原型對(duì)象。在調(diào)用 friend.sayHi() 時(shí)發(fā)生錯(cuò)誤,因?yàn)閒riend 指向的原型中不包含以該名字命名的屬性。

重寫原型對(duì)象切斷了現(xiàn)有原型與任何之前已經(jīng)存在的對(duì)象實(shí)例之間的聯(lián)系,這些實(shí)例仍然引用的是最初的原型。

一切都是對(duì)象

這部分與原型沒(méi)什么大關(guān)系,只是看到了覺(jué)有幫助,就插到這里了,莫要見怪 :)

當(dāng)然,也不是所有的都是對(duì)象,值類型就不是對(duì)象。

舉個(gè)不太容易理解的例子,函數(shù)作為對(duì)象時(shí),其屬性還是函數(shù)的例子。

var fn = function () {
    alert(100);
};

fn.a = 10;
fn.b = function () {
    alert(123);
};
fn.c = {
    name: "福布斯",
    year: 1968
};

上段代碼中,函數(shù)就作為對(duì)象被賦值了a、b、c三個(gè)屬性,第二個(gè)屬性值就是函數(shù),這個(gè)有用嗎?
可以看看jQuery源碼。

在jQuery源碼中,“jQuery”或者“$”,這個(gè)變量其實(shí)是一個(gè)函數(shù),不信可以用 typeof 驗(yàn)證一下。

console.log(typeof $);  // function
console.log($.trim(" ABC "));

驗(yàn)明正身!的確是個(gè)函數(shù)。而經(jīng)常使用的 $.trim() 也是個(gè)函數(shù)。

很明顯,這就是在 $ 或者 jQuery 函數(shù)上加了一個(gè) trim 屬性,屬性值是函數(shù),作用是截取前后空格。要習(xí)慣的把js中的一切看作對(duì)象,只要是對(duì)象,就是屬性的集合,屬性是鍵值對(duì)的形式。

參考資料

理解JavaScript原型

深入理解javascript原型和閉包(1)——一切都是對(duì)象

JavaScript探秘:強(qiáng)大的原型和原型鏈

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

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

相關(guān)文章

  • 重學(xué)前端學(xué)習(xí)筆記(八)--JavaScript中的原型和類

    摘要:用構(gòu)造器模擬類的兩種方法在構(gòu)造器中修改,給添加屬性修改構(gòu)造器的屬性指向的對(duì)象,它是從這個(gè)構(gòu)造器構(gòu)造出來(lái)的所有對(duì)象的原型。 筆記說(shuō)明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時(shí)間開的一個(gè)專欄,每天10分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過(guò)程的一些要點(diǎn)筆記以及感悟,完整的可以加入winter的專欄學(xué)習(xí)【原文有winter的語(yǔ)音】,如有侵權(quán)請(qǐng)聯(lián)系我,郵箱:kai...

    nanfeiyan 評(píng)論0 收藏0
  • 重學(xué)前端學(xué)習(xí)筆記(八)--JavaScript中的原型和類

    摘要:用構(gòu)造器模擬類的兩種方法在構(gòu)造器中修改,給添加屬性修改構(gòu)造器的屬性指向的對(duì)象,它是從這個(gè)構(gòu)造器構(gòu)造出來(lái)的所有對(duì)象的原型。 筆記說(shuō)明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時(shí)間開的一個(gè)專欄,每天10分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過(guò)程的一些要點(diǎn)筆記以及感悟,完整的可以加入winter的專欄學(xué)習(xí)【原文有winter的語(yǔ)音】,如有侵權(quán)請(qǐng)聯(lián)系我,郵箱:kai...

    k00baa 評(píng)論0 收藏0
  • 重學(xué)前端學(xué)習(xí)筆記(八)--JavaScript中的原型和類

    摘要:用構(gòu)造器模擬類的兩種方法在構(gòu)造器中修改,給添加屬性修改構(gòu)造器的屬性指向的對(duì)象,它是從這個(gè)構(gòu)造器構(gòu)造出來(lái)的所有對(duì)象的原型。 筆記說(shuō)明 重學(xué)前端是程劭非(winter)【前手機(jī)淘寶前端負(fù)責(zé)人】在極客時(shí)間開的一個(gè)專欄,每天10分鐘,重構(gòu)你的前端知識(shí)體系,筆者主要整理學(xué)習(xí)過(guò)程的一些要點(diǎn)筆記以及感悟,完整的可以加入winter的專欄學(xué)習(xí)【原文有winter的語(yǔ)音】,如有侵權(quán)請(qǐng)聯(lián)系我,郵箱:kai...

    Render 評(píng)論0 收藏0
  • javascript對(duì)象和原型對(duì)象學(xué)習(xí)筆記

    摘要:例例通過(guò)原型鏈來(lái)檢測(cè)對(duì)象所調(diào)用的方法是否存在,存在在哪個(gè)原型對(duì)象上除了在對(duì)象對(duì)象中存在外,其他方法都是通過(guò)原型鏈的方法在上找到并調(diào)用。 前言 學(xué)習(xí)了解JavaScript對(duì)象的繼承機(jī)制 JavaScript Object 概念 Object是js的基本數(shù)據(jù)結(jié)構(gòu)的一種,屬于引用類型。 對(duì)象的創(chuàng)建方法 對(duì)象字面量寫法 構(gòu)造函數(shù),通過(guò)構(gòu)造函數(shù)來(lái)創(chuàng)建對(duì)象實(shí)例 Object()構(gòu)造函數(shù) cre...

    niceforbear 評(píng)論0 收藏0
  • JavaScript學(xué)習(xí)第十天筆記(繼承)

    摘要:繼承原型鏈如果構(gòu)造函數(shù)或?qū)ο蟮脑椭赶驑?gòu)造函數(shù)或?qū)ο?,的原型再指向?gòu)造函數(shù)或?qū)ο螅源祟愅?,最終的構(gòu)造函數(shù)或?qū)ο蟮脑椭赶虻脑汀? 繼承 原型鏈 如果構(gòu)造函數(shù)或?qū)ο驛的原型指向構(gòu)造函數(shù)或?qū)ο驜,B的原型再指向構(gòu)造函數(shù)或?qū)ο驝,以此類推,最終的構(gòu)造函數(shù)或?qū)ο蟮脑椭赶騉bject的原型。由此形成了一條鏈狀結(jié)構(gòu),被稱之為原型鏈。按照上述的描述,在B中定義的屬性或方法,可以在A中使用并不需要...

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

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

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<