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

溫馨提示×

溫馨提示×

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

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

JS關于高頻題 原型與原型鏈的面試

發布時間:2020-07-22 10:36:32 來源:億速云 閱讀:172 作者:Leah 欄目:web開發

JS關于高頻題 原型與原型鏈的面試?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

國際慣例,讓我們先拋出問題:

  • 什么是原型、原型鏈
  • 它們有什么特點
  • 它們能做什么
  • 怎么確定它們的關系

或許你已經有答案,或許你開始有點疑惑,無論是 get 新技能或是簡單的溫習一次,讓我們一起去探究一番吧

如果文章中有出現紕漏、錯誤之處,還請看到的小伙伴多多指教,先行謝過

原型

JavaScript 是基于原型的

我們創建的每個函數都有一個 prototype(原型) 屬性,這個屬性是一個指針,指向一個對象,而這個對象的用途是包含可以由特定類型的所有實例共享的屬性和方法。

簡單來說,就是當我們創建一個函數的時候,系統就會自動分配一個 prototype屬性,可以用來存儲可以讓所有實例共享的屬性和方法

用一張圖來表示就更加清晰了:

JS關于高頻題 原型與原型鏈的面試

圖解:

  • 每一個構造函數都擁有一個 prototype 屬性,這個屬性指向一個對象,也就是原型對象
  • 原型對象默認擁有一個 constructor 屬性,指向指向它的那個構造函數
  • 每個對象都擁有一個隱藏的屬性 __proto__,指向它的原型對象
function Person(){}

var p = new Person();

p.__proto__ === Person.prototype // true

Person.prototype.constructor === Person // true

那么,原型對象都有哪些特點呢

原型特點

function Person(){}
Person.prototype.name = 'tt';
Person.prototype.age = 18;
Person.prototype.sayHi = function() {
    alert('Hi');
}
var person1 = new Person();
var person2 = new Person();
person1.name = 'oo';
person1.name // oo
person1.age // 18
perosn1.sayHi() // Hi
person2.age // 18
person2.sayHi() // Hi

從這段代碼我們不難看出:

  • 實例可以共享原型上面的屬性和方法
  • 實例自身的屬性會屏蔽原型上面的同名屬性,實例上面沒有的屬性會去原型上面找

既然原型也是對象,那我們可不可以重寫這個對象呢?答案是肯定的

function Person() {}
Person.prototype = {
    name: 'tt',
    age: 18,
    sayHi() {
        console.log('Hi');
    }
}

var p = new Person()

只是當我們在重寫原型鏈的時候需要注意以下的問題:

function Person(){}
var p = new Person();
Person.prototype = {
    name: 'tt',
    age: 18
}

Person.prototype.constructor === Person // false

p.name // undefined

一圖勝過千言萬語

JS關于高頻題 原型與原型鏈的面試

  • 在已經創建了實例的情況下重寫原型,會切斷現有實例與新原型之間的聯系
  • 重寫原型對象,會導致原型對象的 constructor 屬性指向 Object ,導致原型鏈關系混亂,所以我們應該在重寫原型對象的時候指定 constructor( instanceof 仍然會返回正確的值)
Person.prototype = {
    constructor: Person
}

注意:以這種方式重設 constructor 屬性會導致它的 Enumerable 特性被設置成 true(默認為false)

既然現在我們知道了什么是 prototype(原型)以及它的特點,那么原型鏈又是什么呢?

原型鏈

JavaScript 中所有的對象都是由它的原型對象繼承而來。而原型對象自身也是一個對象,它也有自己的原型對象,這樣層層上溯,就形成了一個類似鏈表的結構,這就是原型鏈

同樣的,我們使用一張圖來描述

JS關于高頻題 原型與原型鏈的面試

  • 所有原型鏈的終點都是 Object 函數的 prototype 屬性
  • Objec.prototype 指向的原型對象同樣擁有原型,不過它的原型是 null ,而 null 則沒有原型

清楚了原型鏈的概念,我們就能更清楚地知道屬性的查找規則,比如前面的 p 實例屬性.如果自身和原型鏈上都不存在這個屬性,那么屬性最終的值就是 undefined ,如果是方法就會拋出錯誤

class類

ES6 提供了 Class(類) 這個概念,作為對象的模板,通過 class 關鍵字,可以定義類

為什么會提到 class

ES6class 可以看作只是一個語法糖,它的絕大部分功能,ES5 都可以做到,新的 class 寫法只是讓對象原型的寫法更加清晰、更像面向對象編程的語法而已

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

// 可以這么改寫
function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};

class 里面定義的方法,其實都是定義在構造函數的原型上面實現實例共享,屬性定義在構造函數中,所以 ES6 中的類完全可以看作構造函數的另一種寫法

除去 class 類中的一些行為可能與 ES5 存在一些不同,本質上都是通過原型、原型鏈去定義方法、實現共享。所以,還是文章開始那句話  JavaScript是基于原型的

更多 class 問題,參考這里

關系判斷

instanceof

最常用的確定原型指向關系的關鍵字,檢測的是原型,但是只能用來判斷兩個對象是否屬于實例關系, 而不能判斷一個對象實例具體屬于哪種類型

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

p instanceof Person // true
p instanceof Object // true
hasOwnProperty

通過使用 hasOwnProperty 可以確定訪問的屬性是來自于實例還是原型對象

function Person() {}
Person.prototype = {
    name: 'tt'
}
var p = new Person();
p.age = 15;

p.hasOwnProperty('age') // true
p.hasOwnProperty('name') // false

原型鏈的問題

由于原型鏈的存在,我們可以讓很多實例去共享原型上面的方法和屬性,方便了我們的很多操作。但是原型鏈并非是十分完美的

function Person(){}
Person.prototype.arr = [1, 2, 3, 4];

var person1 = new Person();
var person2 = new Person();

person1.arr.push(5) 
person2.arr // [1, 2, 3, 4, 5]

引用類型,變量保存的就是一個內存中的一個指針。所以,當原型上面的屬性是一個引用類型的值時,我們通過其中某一個實例對原型屬性的更改,結果會反映在所有實例上面,這也是原型 共享 屬性造成的最大問題

另一個問題就是我們在創建子類型(比如上面的 p)時,沒有辦法向超類型( Person )的構造函數中傳遞參數

關于JS關于高頻題 原型與原型鏈的面試問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

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

AI

遵化市| 汾西县| 禹州市| 青冈县| 林州市| 敖汉旗| 康乐县| 延寿县| 定结县| 雷州市| 柏乡县| 六盘水市| 南丰县| 桃园县| 蕲春县| 鹿泉市| 梅州市| 疏勒县| 台安县| 上高县| 武城县| 阳新县| 红安县| 平邑县| 平和县| 珲春市| 安龙县| 即墨市| 四平市| 将乐县| 子长县| 调兵山市| 新乡县| 岢岚县| 合川市| 郯城县| 平顺县| 治县。| 阳原县| 南部县| 寿宁县|