国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

進(jìn)擊JavaScript之(四)原型與原型鏈

XBaron / 2416人閱讀

摘要:每一個(gè)由構(gòu)造函數(shù)創(chuàng)建的對(duì)象都會(huì)默認(rèn)的連接到該神秘對(duì)象上。在構(gòu)造方法中也具有類似的功能,因此也稱其為類實(shí)例與對(duì)象實(shí)例一般是指某一個(gè)構(gòu)造函數(shù)創(chuàng)建出來的對(duì)象,我們稱為構(gòu)造函數(shù)的實(shí)例實(shí)例就是對(duì)象。表示該原型是與什么構(gòu)造函數(shù)聯(lián)系起來的。

本文您將看到以下內(nèi)容:

傳統(tǒng)構(gòu)造函數(shù)的問題

一些相關(guān)概念

認(rèn)識(shí)原型

構(gòu)造、原型、實(shí)例三角結(jié)構(gòu)圖

對(duì)象的原型鏈

函數(shù)的構(gòu)造函數(shù)Function

一句話說明什么是原型:原型就是一個(gè)JavaScript對(duì)象,原型能存儲(chǔ)我們的方法,構(gòu)造函數(shù)創(chuàng)建出來的實(shí)例對(duì)象能夠引用原型中的方法。

一、傳統(tǒng)構(gòu)造函數(shù)的問題

有如下代碼

function Foo(){
    this.sayHello = function(){
     }
}

由于對(duì)象是調(diào)用new Foo()所創(chuàng)建出來的,因此每一個(gè)對(duì)象在創(chuàng)建的時(shí)候,函數(shù) sayHello 都會(huì)唄創(chuàng)建一次

那么有沒一個(gè)對(duì)象都含有一個(gè)獨(dú)立的,不同的,但是功能邏輯一樣的函數(shù),比如:{} == {}

在代碼中方法就會(huì)消耗性能,最典型的資源就越是內(nèi)存

這里最好的方法就是將函數(shù)放在構(gòu)造函數(shù)之外,那么在構(gòu)造函數(shù)中引用該函數(shù)即可

function sayHello () {}
function Foo () {
    this.say = sayHello;
}

會(huì)在開發(fā)中變得困難:引入框架危險(xiǎn),代碼繁冗不好維護(hù)。解決方法就是如果外面的函數(shù)不占用其名字,而且在函數(shù)名下。

每一個(gè)函數(shù)在定義的時(shí)候,有一個(gè)神秘對(duì)象(就是原型對(duì)象,暫且這么稱呼)被創(chuàng)建出來。

每一個(gè)由構(gòu)造函數(shù)創(chuàng)建的對(duì)象都會(huì)默認(rèn)的連接到該神秘對(duì)象上。

var f1 = new Foo();
var f2 = new Foo();
f1.sayHello();    //如果f1沒有sayHello那么就會(huì)在Foo.prototype中去找

由構(gòu)造函數(shù)創(chuàng)建出來的眾多對(duì)象共享一個(gè)對(duì)象就是:構(gòu)造函數(shù).prototype

只需要將共享的東西,重復(fù)會(huì)多占用內(nèi)存的東西放到構(gòu)造函數(shù).prototype中,那么所有的對(duì)象就可以共享了。

function Foo(){}
Foo.prototype.sayHello = function(){
    console.log("….");
}
var f1 = new Foo();
f1.sayHello();
var f2 = new Foo();
f2.sayHello();
console.log(f1.sayHello === f2.sayHello); // true
二、一些相關(guān)概念

類class:在JS中就是構(gòu)造函數(shù)

在傳統(tǒng)的面向?qū)ο笳Z言中,使用一個(gè)叫類的東西定義模板,然后使用模板創(chuàng)建對(duì)象。

在構(gòu)造方法中也具有類似的功能,因此也稱其為類

實(shí)例(instance)與對(duì)象(object)

實(shí)例一般是指某一個(gè)構(gòu)造函數(shù)創(chuàng)建出來的對(duì)象,我們稱為XXXX 構(gòu)造函數(shù)的實(shí)例

實(shí)例就是對(duì)象。對(duì)象是一個(gè)泛稱

實(shí)例與對(duì)象是一個(gè)近義詞

鍵值對(duì)與屬性和方法

在JS中鍵值對(duì)的集合稱為對(duì)象

如果值為數(shù)據(jù)(非函數(shù)),就稱該鍵值對(duì)為屬性

如果值為函數(shù)(方法),就稱該鍵值對(duì)為方法method

父類與子類(基類和派生類)

傳統(tǒng)的面向?qū)ο笳Z言中使用類來實(shí)現(xiàn)繼承那么就有父類、子類的概念

父類又稱為基類,子類又稱為派生類

在JS中沒有類的概念,在JS中常常稱為父對(duì)象,子對(duì)象,基對(duì)象,派生對(duì)象。

三、認(rèn)識(shí)原型

在JavaScript中,原型也是一個(gè)對(duì)象,通過原型可以實(shí)現(xiàn)對(duì)象的屬性繼承,JavaScript的對(duì)象中都包含了一個(gè)[[Prototype]]內(nèi)部屬性,這個(gè)屬性所對(duì)應(yīng)的就是該對(duì)象的原型。

[[Prototype]]作為對(duì)象的內(nèi)部屬性,是不能被直接訪問的。所以為了方便查看一個(gè)對(duì)象的原型,F(xiàn)irefox和Chrome中提供了__proto__這個(gè)非標(biāo)準(zhǔn)(不是所有瀏覽器都支持)的訪問器(ECMA引入了標(biāo)準(zhǔn)對(duì)象原型訪問器"Object.getPrototype(object)")。

下面通過一個(gè)例子來看看原型相關(guān)概念:

function Person() {}
// 神秘對(duì)象就是Person.prototype
//那么只有使用構(gòu)造函數(shù)才可以訪問它
var o = new Person();
//以前不能直接使用o來訪問神秘對(duì)象
//現(xiàn)在有了__proto__后,
o.__proto__也可以直接訪問神秘對(duì)象
//那么o.__proto__ === Person.prototype

神秘對(duì)象(原型)中都有一個(gè)屬性constructor,翻譯為 構(gòu)造器 。表示該原型是與什么構(gòu)造函數(shù)聯(lián)系起來的。

__proto__有什么用?可以訪問原型。由于在開發(fā)中除非特殊要求,不要使用實(shí)例去修改原型的成員,因此該屬性開發(fā)時(shí)使用較少。但是在調(diào)試過程中非常方便,可以輕易的訪問原型進(jìn)行查看成員

如果在早期的瀏覽器中使用實(shí)例需要訪問原型如何處理?可以使用實(shí)例對(duì)象訪問構(gòu)造器,然后使用構(gòu)造器訪問原型

var o = new Person();
o.constructor.prototype

如果給實(shí)例繼承自原型的屬性賦值

function Foo();
Foo.prototype.name = "test";
var o1 = new Foo();
var o2 = new Foo();
o1.name = "張三";    // 不是修改原型中的name而是自己增加了一個(gè)name屬性
console.log(o1.name + ","+ o2.name);    // 張三,test
四、構(gòu)造、原型、實(shí)例三角結(jié)構(gòu)圖

對(duì)于如下代碼:

function Person(){}
var p = new Person()

console.log(Person.prototype.constructor); //function Person(){}
console.log(Person.prototype.constructor.name); //Person
console.log(typeof Person.prototype.constructor); //function

console.log(p.__prop__);
console.log(p.__prop__ === Person.prototype);//true

于是他們的關(guān)系圖如下:

五、對(duì)象的原型鏈

凡是對(duì)象就有原型,原型也是對(duì)象。因此凡是給定一個(gè)對(duì)象,那么就可以找到他的原型,原型還有原型,那么如此下去,就構(gòu)成一個(gè)對(duì)象的序列,稱該結(jié)構(gòu)為原型鏈。

問題:

原型鏈到底到什么時(shí)候是一個(gè)頭?

一個(gè)默認(rèn)的原型鏈結(jié)構(gòu)是怎樣的?

原型鏈結(jié)構(gòu)對(duì)已知語法的修正

5.1 原型鏈的結(jié)構(gòu)

凡是使用構(gòu)造函數(shù),創(chuàng)建出對(duì)象,并且沒有利用賦值的方式修改原型,就說該對(duì)象保留默認(rèn)的原型鏈。

默認(rèn)原型鏈結(jié)構(gòu)是什么樣子呢?

function Person(){}
var p = new Person();
//p 具有默認(rèn)的原型鏈

默認(rèn)的原型鏈結(jié)構(gòu)就是:當(dāng)前對(duì)象 -> 構(gòu)造函數(shù).prototype -> Object.prototype -> null

在實(shí)現(xiàn)繼承的時(shí)候,有時(shí)候會(huì)利用替換原型鏈結(jié)構(gòu)的方式實(shí)現(xiàn)原型繼承,那么原型鏈結(jié)構(gòu)就會(huì)發(fā)送改變

function DunizbCollection(){}
DunizbCollection.prototype = [];
var arr = new DunizbCollection();
// arr -> [] -> Array.prototype -> Object.prototype -> null

六、函數(shù)的構(gòu)造函數(shù)Function

在JS中使用Function可以實(shí)例化函數(shù)對(duì)象 。也就是說在JS中函數(shù)與普通對(duì)象一樣,也是一個(gè)對(duì)象類型。函數(shù)是JS中的一等公民。

函數(shù)是對(duì)象,就可以使用對(duì)象的動(dòng)態(tài)特性

函數(shù)是對(duì)象,就有構(gòu)造函數(shù)創(chuàng)建函數(shù)

函數(shù)是對(duì)象,可以創(chuàng)建其它對(duì)象

函數(shù)是唯一可以限定變量作用域的結(jié)果

要解決的問題

Function 如何使用

Function 與函數(shù)的關(guān)系

函數(shù)的原型鏈結(jié)構(gòu)

6.1 函數(shù)是Function的實(shí)例

語法

new Function( arg0,arg1,arg1,….argN, body );

Function 中的參數(shù)全部是字符串

該構(gòu)造函數(shù)的作用是將參數(shù)鏈接起來組成函數(shù)

如果參數(shù)只有一個(gè),那么表示函數(shù)體

如果參數(shù)有多個(gè),最后一個(gè)參數(shù)表示函數(shù)體,前面的所有參數(shù)表示函數(shù)的參數(shù)

如果沒有參數(shù),表示創(chuàng)建一個(gè)空函數(shù)

舉例:創(chuàng)建一個(gè)打印一句話的函數(shù)

// 傳統(tǒng)的
function foo () {
    console.log( "你好" );
}
//Function
var func = new Function( "console.log( "你好" );" );
// 功能上,這里foo 與 func 等價(jià)

再比如,創(chuàng)建一個(gè)空函數(shù)

//傳統(tǒng)
function foo () {}
//Function
var func = new Function();
func();

傳入函數(shù)內(nèi)一個(gè)數(shù)字,打印該函數(shù)

//傳統(tǒng)
function foo ( num ) {
    console.log( num );
}
//Function
var func = new Function( "num" ,"console.log( num )" );
func();
6.2 函數(shù)的原型鏈結(jié)構(gòu)

任意的一個(gè)函數(shù),都是相當(dāng)于Function的實(shí)例,類似于{}與new Object()的關(guān)系。

function foo () {}

上面的代告訴解析器,有一個(gè)對(duì)象叫foo,它是一個(gè)函數(shù);相當(dāng)于new Function()得到一個(gè)函數(shù)對(duì)象

函數(shù)應(yīng)該有什么屬性?答:__proto__

函數(shù)的構(gòu)造函數(shù)是什么?答:Function

函數(shù)應(yīng)該繼承自Function.prototype

Function.prototype繼承自O(shè)bject.prototype

對(duì)于Function,我們還必須知道

Object函數(shù)是Function的一個(gè)實(shí)例

Object作為對(duì)象是繼承自Function.prototype的,又“Function.prototype”繼承自O(shè)bject.prototype

foo.prototype.__proto__ === Object.prototype // true

Function是自己的構(gòu)造函數(shù)

在JS 中任何對(duì)象的老祖宗就是Object.prototype

在JS中任何函數(shù)的老祖宗就是Function.prototype

下面繪制出 Function 的構(gòu)造原型實(shí)例三角形結(jié)構(gòu)

6.3 為什么要使用Function?

Function是使用字符串構(gòu)建函數(shù),那么就可以在程序運(yùn)行過程中構(gòu)建函數(shù).

以前的函數(shù)必須一開始就寫好,再經(jīng)過預(yù)解析,一步一步的運(yùn)行

假定從服務(wù)器里拿到“[1,2,3,4,5]”,將數(shù)組形式的字符串轉(zhuǎn)換成數(shù)組對(duì)象

var arr = ( new Function( "return " + str + " ;" ) )();

推薦閱讀

進(jìn)擊JavaScript之(一)詞法作用域與作用域鏈

進(jìn)擊JavaScript之(二)詞法作用域與作用域鏈

進(jìn)擊JavaScript之(三)玩轉(zhuǎn)閉包

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

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

相關(guān)文章

  • 進(jìn)擊JavaScript(二)詞法作用域作用域

    摘要:一作用域域表示的就是范圍,即作用域,就是一個(gè)名字在什么地方可以使用,什么時(shí)候不能使用。概括的說作用域就是一套設(shè)計(jì)良好的規(guī)則來存儲(chǔ)變量,并且之后可以方便地找到這些變量。 一、作用域 域表示的就是范圍,即作用域,就是一個(gè)名字在什么地方可以使用,什么時(shí)候不能使用。想了解更多關(guān)于作用域的問題推薦閱讀《你不知道的JavaScript上卷》第一章(或第一部分),從編譯原理的角度說明什么是作用域。概...

    denson 評(píng)論0 收藏0
  • 進(jìn)擊JavaScript (七) 原型

    摘要:創(chuàng)建一個(gè)新的對(duì)象即實(shí)例對(duì)象把新對(duì)象的指向后面構(gòu)造函數(shù)的原型對(duì)象。簡(jiǎn)單來驗(yàn)證一下等同與對(duì)象沒有原型對(duì)象的原型對(duì)像等同于構(gòu)造函數(shù)是等同于,構(gòu)造函數(shù)是七原型鏈的作用其實(shí),原型鏈的根本作用就是為了屬性的讀取。 首先說一下,函數(shù)創(chuàng)建的相關(guān)知識(shí) 在JavaScript中,我們創(chuàng)建一個(gè)函數(shù)A(就是聲明一個(gè)函數(shù)), 那么 js引擎 就會(huì)用構(gòu)造函數(shù)Function來創(chuàng)建這個(gè)函數(shù)。所以,所有的函數(shù)的con...

    ivydom 評(píng)論0 收藏0
  • JS面向?qū)ο蠖?this/原型/new原理

    摘要:情況沒有明確作用對(duì)象的情況下,通常為全局對(duì)象例如函數(shù)的回調(diào)函數(shù),它的就是全局對(duì)象。正因如此,機(jī)器可以作為這類對(duì)象的標(biāo)志,即面向?qū)ο笳Z言中類的概念。所以機(jī)器又被稱為構(gòu)造函數(shù)。原型鏈也就是繼承鏈。 JS面向?qū)ο蠖?this/原型鏈/new原理 阮一峰JavaScript教程:面向?qū)ο缶幊?阮一峰JavaScript教程:實(shí)例對(duì)象與 new 命令 阮一峰JavaScript教程:this 關(guān)...

    anRui 評(píng)論0 收藏0
  • 進(jìn)擊JavaScript(三)玩轉(zhuǎn)閉包

    摘要:為了更好的理解,在閱讀此文之前建議先閱讀上一篇進(jìn)擊之詞法作用域與作用域鏈?zhǔn)裁词情]包閉包的含義就是閉合,包起來,簡(jiǎn)單的來說,就是一個(gè)具有封閉功能與包裹功能的結(jié)構(gòu)。在中函數(shù)構(gòu)成閉包。 為了更好的理解,在閱讀此文之前建議先閱讀上一篇《進(jìn)擊JavaScript之詞法作用域與作用域鏈》 1.什么是閉包 閉包的含義就是閉合,包起來,簡(jiǎn)單的來說,就是一個(gè)具有封閉功能與包裹功能的結(jié)構(gòu)。所謂的閉包就是...

    cyixlq 評(píng)論0 收藏0
  • 進(jìn)擊JavaScript(一)變量聲明提升

    摘要:如下代碼輸出的結(jié)果是代碼執(zhí)行分為兩個(gè)大步預(yù)解析的過程代碼的執(zhí)行過程預(yù)解析與變量聲明提升程序在執(zhí)行過程中,會(huì)先將代碼讀取到內(nèi)存中檢查,會(huì)將所有的聲明在此進(jìn)行標(biāo)記,所謂的標(biāo)記就是讓解析器知道有這個(gè)名字,后面在使用名字的時(shí)候不會(huì)出現(xiàn)未定義的錯(cuò)誤。 showImg(https://segmentfault.com/img/remote/1460000012922850); 如下代碼輸出的結(jié)果是...

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

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

0條評(píng)論

閱讀需要支付1元查看
<