首頁 > 常見問題 > js原型和原型鍊是什麼

js原型和原型鍊是什麼

百草
發布: 2023-06-14 11:57:11
原創
8129 人瀏覽過

js原型和原型鍊是:1、原型,所有的函數預設都有一個「prototype」這樣公有且不可列舉的屬性,它會指向另一個對象,這個物件就是原型。 2.原型鏈,當存取物件的屬性或方法時,首先物件會從自身去找,找不到就會往原型中去找,也就是它建構函式的「prototype」中,如果原型中找不到,即建構函式中也沒有該屬性,就會往原型後面的原型上去找,這樣就形成了鍊式的結構,稱為原型鏈。

js原型和原型鍊是什麼

本教學作業系統:windows10系統、JavaScript  ECMAScript 2021版本、DELL G3電腦。

一、原型

原型:所有的函數預設都有一個「prototype」這樣公有且不可列舉的屬性,它會指向另一個對象,這個對象就是原型。每當定義一個物件(函數也是物件)時,就會產生一個__proto__屬性,被稱為隱式原型;這個__proto__屬性指向的是這個物件的建構函數的prototype,被稱為顯式原型。每一個物件都會從原型中「繼承」屬性。

首先看一個例子,建立一個Student類,並建立類別的實例物件student:

class Student{
    constructor(name, score) {
        this.name = name;
        this.score = score;
    }
    introduce() {
        console.log(`我是${this.name},考了${this.score}分。`)
    }
}
const student = new Student('张三', 99)
console.log('student', student); // student Student { name: '张三', score: 99}
student.introduce(); // 我是张三,考了99分。
登入後複製

控制台能存取到屬性和方法。

js原型和原型鍊是什麼

但直接在控制台輸入student,會發現只有name和score屬性,沒有introduce方法,但有一個[[Prototype]]屬性,用兩個中括號括起來。

js原型和原型鍊是什麼

把[[Prototype]]展開,會發現introduce方法在[[Prototype]]中。

js原型和原型鍊是什麼

[[Prototype]]屬性被稱為student物件的隱式原型。當我們要去找一個物件的屬性或方法時,如果在目前物件上找不到,就會去當前物件的隱式原型[[Prototype]]屬性上去找。

可透過.__proto__屬性存取原型,注意__proto__兩邊分別有兩條底線。

js原型和原型鍊是什麼

而Student()建構子也有一個prototype屬性,Student()建構子的prototype屬性其實等於student物件的__proto__屬性。

1.js原型和原型鍊是什麼

下面用一張圖來說明:

js原型和原型鍊是什麼

#因此,建構子的prototype屬性就等於實例物件的__proto__屬性,建構函數的prototype屬性稱為明確原型,實例物件的__proto__屬性稱為隱式原型。

二、原型鏈

原型鏈:當存取一個物件的屬性或方法時,首先物件會從自身去找,如果找不到,就會往原型中去找,即__proto__,也就是它構造函數的prototype中;如果原型中找不到,即構造函數中也沒有該屬性,因為構造函數也是對象,也有__proto__,就會往原型上去找,這樣就形成了鍊式的結構,稱為原型鏈,本質描述的是物件的一種繼承關係。

再來看一個例子,建立一個Person類,再建立一個Teacher類別繼承自Person類,並建立實例物件teacher:

class Person {
    constructor(name) {
        this.name = name;
    }
    drink(){
        console.log('喝水');
    }
}
class Teacher extends Person {
    constructor(name, subject) {
        super(name);
        this.subject = subject;
    }
    teach() {
        console.log(`我是${this.name}, 教${this.subject}。`)
    }
}
const teacher = new Teacher('哈默', '前端开发')
console.log('teacher', teacher);
teacher.teach();
teacher.drink();
登入後複製

控制台輸出如下,teacher可以執行teach()和drink()方法。

js原型和原型鍊是什麼

展開teacher對象,發現找不到這兩個方法,於是去找對象的原型,即__proto__屬性,找到teach()方法,再展開下一層__proto__屬性,找到drink()方法。

js原型和原型鍊是什麼

下面用一張圖說明:

js原型和原型鍊是什麼

#

可以看到,teacher实例对象本身是没有teach()方法的,这时就会去teacher对象的__proto__隐式原型指向的Teacher.prototype显式原型上去找,此时找到了teach()方法并执行;同时,Teacher.prototype上仍然没有找到drink()方法,而Teacher.prototype也是一个对象,有自己的__proto__隐式原型,那么就去Teacher.prototype.__proto__上去找,Teacher.prototype.__proto__会指向Person()构造函数的显式原型Person.prototype,此时找到了drink()方法并执行,这就是原型链。

注:

(1)通过__proto__形成原型链而非protrotype。

(2)__proto__属性是对象所独有的。

(3)prototype属性是函数所独有的。但是由于JS中函数也是一种对象,所以函数也拥有__proto__属性。

三、判断对象自身是否有某属性或方法

hasOwnProperty()方法会返回一个布尔值,用于判断对象自身是否有某属性或方法。返回true,代表是该对象自身的属性或方法;返回false,代表是该对象原型上的属性或方法。

由于Person类继承自Object类,那么执行teacher.hasOwnProperty()方法时,实际会找到Object.prototype中的hasOwnProperty()方法并执行。

因此,所有继承了Object的对象都会继承到hasOwnProperty方法。

同时可以看到,Object.prototype.__proto__ 的值为 null ,即 Object.prototype 没有原型,所以可以想象在原型链中,当找到顶层原型还没有属性时,那就是没有这个属性,返回返回undefined。

js原型和原型鍊是什麼

instanceof 运算符:用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

看一个例子,使用typeof判断array的数据类型时,返回的是object,因此无法使用typeof判断array的类型。

const object = {};
const array = [];
// 使用typeof判断数据类型,array返回的是object 
console.log(typeof object); // object
console.log(typeof array); // object
登入後複製

下面使用instanceof运算符判断array的数据类型:

// 使用instanceof判断数据类型
const flagObject = object instanceof Array;
const flagArray = array instanceof Array;
console.log(flagObject); // false
console.log(flagArray); // true
登入後複製

object instanceof Array返回false,表示Array.prototype不在object的原型链上;array instanceof Array返回true,表示Array.prototype在array的原型链上,由此可以区分object和array的数据类型。

也可通过控制台查看object和array的原型。

注:[] instanceof Object 为 true

以上是js原型和原型鍊是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板