91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用JavaScript進階(四)原型與原型鏈

發布時間:2020-07-28 11:50:30 來源:億速云 閱讀:156 作者:小豬 欄目:web開發

小編這次要給大家分享的是如何使用JavaScript進階(四)原型與原型鏈,文章內容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。

一句話說明什么是原型:原型就是一個JavaScript對象,原型能存儲我們的方法,構造函數創建出來的實例對象能夠引用原型中的方法。

一、傳統構造函數的問題

有如下代碼

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

由于對象是調用new Foo()所創建出來的,因此每一個對象在創建的時候,函數 sayHello 都會唄創建一次

那么有沒一個對象都含有一個獨立的,不同的,但是功能邏輯一樣的函數,比如:{} == {}

在代碼中方法就會消耗性能,最典型的資源就越是內存

這里最好的方法就是將函數放在構造函數之外,那么在構造函數中引用該函數即可

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

會在開發中變得困難:引入框架危險,代碼繁冗不好維護。解決方法就是如果外面的函數不占用其名字,而且在函數名下。

每一個函數在定義的時候,有一個神秘對象(就是原型對象,暫且這么稱呼)被創建出來。

每一個由構造函數創建的對象都會默認的連接到該神秘對象上。

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

由構造函數創建出來的眾多對象共享一個對象就是:構造函數.prototype

只需要將共享的東西,重復會多占用內存的東西放到構造函數.prototype中,那么所有的對象就可以共享了。

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

二、一些相關概念

類class:在JS中就是構造函數

  • 在傳統的面向對象語言中,使用一個叫類的東西定義模板,然后使用模板創建對象。
  • 在構造方法中也具有類似的功能,因此也稱其為類

實例(instance)與對象(object)

  • 實例一般是指某一個構造函數創建出來的對象,我們稱為XXXX 構造函數的實例
  • 實例就是對象。對象是一個泛稱
  • 實例與對象是一個近義詞

鍵值對與屬性和方法

  • 在JS中鍵值對的集合稱為對象
  • 如果值為數據(非函數),就稱該鍵值對為屬性
  • 如果值為函數(方法),就稱該鍵值對為方法method

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

  • 傳統的面向對象語言中使用類來實現繼承那么就有父類、子類的概念
  • 父類又稱為基類,子類又稱為派生類
  • 在JS中沒有類的概念,在JS中常常稱為父對象,子對象,基對象,派生對象。

三、認識原型

在JavaScript中,原型也是一個對象,通過原型可以實現對象的屬性繼承,JavaScript的對象中都包含了一個[[Prototype]]內部屬性,這個屬性所對應的就是該對象的原型。

[[Prototype]]作為對象的內部屬性,是不能被直接訪問的。所以為了方便查看一個對象的原型,Firefox和Chrome中提供了__proto__這個非標準(不是所有瀏覽器都支持)的訪問器(ECMA引入了標準對象原型訪問器"Object.getPrototype(object)")。

下面通過一個例子來看看原型相關概念:

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

神秘對象(原型)中都有一個屬性constructor,翻譯為 構造器 。表示該原型是與什么構造函數聯系起來的。

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

如果在早期的瀏覽器中使用實例需要訪問原型如何處理?可以使用實例對象訪問構造器,然后使用構造器訪問原型

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

如果給實例繼承自原型的屬性賦值

function Foo();
Foo.prototype.name = "test";
var o1 = new Foo();
var o2 = new Foo();
o1.name = "張三"; // 不是修改原型中的name而是自己增加了一個name屬性
console.log(o1.name + ','+ o2.name); // 張三,test

四、構造、原型、實例三角結構圖

對于如下代碼:

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

于是他們的關系圖如下:

如何使用JavaScript進階(四)原型與原型鏈

五、對象的原型鏈

凡是對象就有原型,原型也是對象。因此凡是給定一個對象,那么就可以找到他的原型,原型還有原型,那么如此下去,就構成一個對象的序列,稱該結構為原型鏈。

問題:

  1. 原型鏈到底到什么時候是一個頭?
  2. 一個默認的原型鏈結構是怎樣的?
  3. 原型鏈結構對已知語法的修正

5.1 原型鏈的結構

凡是使用構造函數,創建出對象,并且沒有利用賦值的方式修改原型,就說該對象保留默認的原型鏈。

默認原型鏈結構是什么樣子呢?

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

默認的原型鏈結構就是:當前對象 -> 構造函數.prototype -> Object.prototype -> null

如何使用JavaScript進階(四)原型與原型鏈

在實現繼承的時候,有時候會利用替換原型鏈結構的方式實現原型繼承,那么原型鏈結構就會發送改變

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

如何使用JavaScript進階(四)原型與原型鏈

六、函數的構造函數Function

在JS中使用Function可以實例化函數對象 。也就是說在JS中函數與普通對象一樣,也是一個對象類型。函數是JS中的一等公民。

  1. 函數是對象,就可以使用對象的動態特性
  2. 函數是對象,就有構造函數創建函數
  3. 函數是對象,可以創建其它對象
  4. 函數是唯一可以限定變量作用域的結果

要解決的問題

  1. Function 如何使用
  2. Function 與函數的關系
  3. 函數的原型鏈結構

6.1 函數是Function的實例

語法

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

Function 中的參數全部是字符串

該構造函數的作用是將參數鏈接起來組成函數

  • 如果參數只有一個,那么表示函數體
  • 如果參數有多個,最后一個參數表示函數體,前面的所有參數表示函數的參數
  • 如果沒有參數,表示創建一個空函數

舉例:創建一個打印一句話的函數

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

再比如,創建一個空函數

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

傳入函數內一個數字,打印該函數

//傳統
function foo ( num ) {
 console.log( num );
}
//Function
var func = new Function( "num" ,"console.log( num )" );
func();

6.2 函數的原型鏈結構

任意的一個函數,都是相當于Function的實例,類似于{}與new Object()的關系。

function foo () {}

上面的代告訴解析器,有一個對象叫foo,它是一個函數;相當于new Function()得到一個函數對象

  • 函數應該有什么屬性?答:__proto__
  • 函數的構造函數是什么?答:Function
  • 函數應該繼承自Function.prototype
  • Function.prototype繼承自Object.prototype

對于Function,我們還必須知道

  • Object函數是Function的一個實例
  • Object作為對象是繼承自Function.prototype的,又“Function.prototype”繼承自Object.prototype

    foo.prototype.__proto__ === Object.prototype // true
     
  • Function是自己的構造函數
  • 在JS 中任何對象的老祖宗就是Object.prototype
  • 在JS中任何函數的老祖宗就是Function.prototype

下面繪制出 Function 的構造原型實例三角形結構

如何使用JavaScript進階(四)原型與原型鏈

6.3 為什么要使用Function?

Function是使用字符串構建函數,那么就可以在程序運行過程中構建函數.

以前的函數必須一開始就寫好,再經過預解析,一步一步的運行

假定從服務器里拿到“[1,2,3,4,5]”,將數組形式的字符串轉換成數組對象

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

看完這篇關于如何使用JavaScript進階(四)原型與原型鏈的文章,如果覺得文章內容寫得不錯的話,可以把它分享出去給更多人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

旅游| 南靖县| 烟台市| 祁阳县| 屏东县| 石楼县| 含山县| 平顶山市| 炉霍县| 通山县| 封丘县| 华亭县| 于田县| 丹阳市| 罗定市| 灌阳县| 全州县| 宁陵县| 珠海市| 阿合奇县| 德惠市| 昭苏县| 石嘴山市| 中卫市| 灵山县| 辉县市| 鹿泉市| 西乌| 临沂市| 长海县| 东丽区| 西吉县| 黄山市| 通海县| 镇平县| 仲巴县| 彭山县| 辽阳市| 祁门县| 东兴市| 遵义市|