Jadual Kandungan
对象原型
原型链
使用原型
原型继承
修改原型
ES6 的 Class
总结
Rumah hujung hadapan web tutorial js 了解JavaScript中的对象原型和原型链

了解JavaScript中的对象原型和原型链

Nov 20, 2020 pm 05:26 PM
javascript rantai prototaip

本篇文章带大家介绍一下JavaScript中的对象原型和原型链。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

了解JavaScript中的对象原型和原型链

对象原型

相信大家都这样用过  map

let arr = [0, 1, 2]
let doubleArr = arr.map(c => c * 2)
console.log(doubleArr) // 0, 2, 4
Salin selepas log masuk

不知道你有没有想过, arr 本身并没有设定 map 属性,那为什么可以用 map 这个函数呢?

把它打印出来看看:

console.log(arr)
// 0: 0
// 1: 1
// 2: 2
// length: 3
// __proto__: Array(0)
Salin selepas log masuk

出现了一个名为 __proto__ 的对象,如果再将其展开,就会看到所有 Array 对象可以使用的函数;当然我们也可以在其中找到 map 函数,而这也正是例子中所调用的 arr.map 这个函数:

console.log(arr.map === arr.__proto__.map) // true
Salin selepas log masuk

这里出现的 __proto__ 对象,也就是所谓的 原型对象(Prototype)

不同于 Java、C# 等基于类(Class) 的面向对象语言,通过定义类、创建实例、指定继承等方式来传递属性及方法;Javascript 则是个基于原型(Prototype)的对语言 ,通过预先建立出的原型对象,当新对象建立时指定对象的原型要参照哪个原型对象。

而当我们调用对象的属性或方法时,若对象本身没有这个属性或方法,JavaScript 会自动寻找它原型中的方法,这也就是为什么可以直接调用 arr.map 而不会出错的原因。

原型链

你可能已经发现在前面的例子中,__proto__ 对象里仍然有 __proto__ 属性:

console.log(arr.__proto__) // Array 的 Prototype
console.log(arr.__proto__.__proto__) // Object 的 Prototype
console.log(arr.__proto__.__proto__.__proto__) // null
Salin selepas log masuk

在上述机制中,每当对象建立时都会绑定原型,既然对象都有原型,对象原型本身也是对象,自然也不例外;由这个例子中我们可以看出:

  • arr 是数组实例,原型是 Array
  • arr.__proto__ 是数组的原型,原型是 Object
  • arr.__proto__.__proto__ 是对象的原型,原型是 null
  • arr.__proto__.__proto__.__proto__ 是 null,没有任何属性

由于每个对象都有原型,这样就形成了一个关联一个、层层相互依赖的从属关系,我们把它们叫做原型链(Prototype Chain) ;通过这种机制,让对象得以使用原型中的属性和方法,并凭借原型链一层一层的按顺序继承,让对象能拥有原型链上所有原型的功能,这就是 JavaScript 对象背后的运作机制。

补充:在 JavaScript 中,几乎每个原型链的末端都会是 Object,并最后指向到  null

使用原型

说了这么多,该来点代码了,接下来就来练习一下原型的建立、设定及修改吧。

先来创建一个新的对象构造函数:

function Person(name) {
  this.name = name
}Person.prototype.hello = function () {
  console.log(`Hello ${this.name}.`)
}let gary = new Person('Gary')
gary.hello() // Hello Gary.Object.getPrototypeOf(gary) // {hello: ƒ, constructor: ƒ}
Salin selepas log masuk

上面的例子创建了一个简单的对象构造函数 Person(),并在构造函数中设定对象属性。对象的方法中,由于方法不需要让每个对象都独自拥有一份,以避免造成冗余的内存消耗,应该要像前面 Array.prototype.map 的例子那样把对象的方法设定给原型对象(Person.prototype),让这个构造函数创建出来的对象都可以共用这些方法。最后建立一个新的 Person 对象,并通过 getPrototypeOf(obj) 获取新产生对象的原型。

Q:为什么不直接用 __proto__ 获取原型对象?
A:因为虽然 __proto__ 被几乎所有的浏览器支持,但它是非标准属性;通过 getPrototypeOf 取得对象的原型是正确的方法。

提醒:Person.prototype 不是 Person 的原型,而是构造函数执行后所建立的新对象的原型;千万不要把构造函数的 prototype 属性对象的原型搞混!

原型继承

接着再创建新的对象原型,并继承 Person

function Engineer(name, skill) {
  Person.call(this, name)
  this.skill = skill
}
Engineer.prototype = Object.create(Person.prototype)
Engineer.prototype.constructor = Engineerlet alice = new Engineer('Alice', 'JavaScript')
alice.hello() // Hello Alice.
console.log(alice.skill) // JavaScriptObject.getPrototypeOf(alice) 
// Person {constructor: ƒ}
Salin selepas log masuk

这里建立了新的对象 Engineer 的原型,并通过 Engineer.prototype 的指定,让它的原型继承自 Person.prototype,最后再重新设定 Engineer.prototype.constructor,让构造函数重新指回自己;这样就完成了最基本的原型继承。

Q:为什么需要重新设定 constructor
A:这边功过 Object.create 复制了 Person.prototype 的全部属性,连同 constructor 属性都会被覆盖掉,如果 constructor 属性错误,在做 instanceof 判断时会产生错误的结果;因此这边设定继承时需要再次将 constructor 重新指定回构造函数本身。

修改原型

原型的引用、继承是直接参照到原型对象上,并非是在每个对象都复制一份原型;因此可以利用这个特性,在原型上增加自定义的属性和方法,让所有该类型的对象都能得到新方法;许多针对旧版浏览器的 Polyfill 就是这样实现的。

例如我们在写 Vue 项目的时候,可能都有做过类似的操作,把共用性高的属性方法放到  Vue.prototype 中:

Object.defineProperty(Vue.prototype, '$date', { value: dateTimeFormat })
// 之后就可以这样用
vm.$date(dateObj)
Salin selepas log masuk

这样的确很方便,但也要提醒开大家,当我们在做原型修改的时候要特别小心。接着刚才的例子,如果尝试对 Person 原型中的方法做个修改:

Person.prototype.hello = function () {
  console.log(`Bye ${this.name}.`)
}gary.hello() // Bye Gary.
alice.hello() // Bye Alice.
Salin selepas log masuk

如结果所示,当对象原型做修改时,所有原型链上有这个原型的对象,通通都会受到影响,不管对象是在修改前还是修改后创建的。

建议大家除非是 Polyfill,否则应该要极力避免对原生对象的原型进行修改,防止造成可能的意外结果。

ES6 的 Class

看完前面这一大段,是不是觉得心很累?别担心,从 ES6 开始添加了 Class 语法糖,使开发者体验提升了很多。下面把前面的例子用  Class 重构一下:

class Person {
  constructor (name){
    this.name = name
  }
  // 方法会自动放到 Person.prototype
  hello() {
    console.log(`Hello ${this.name}.`)
  }
}class Engineer extends Person {
  constructor (name, skill){
    super(name) // 调用 Person 的构造函数
    this.skill = skill
  }
}let alice = new Engineer('Alice', 'JavaScript')
alice.hello() // Hello Alice.Object.getPrototypeOf(alice) 
// Person {constructor: ƒ}
Salin selepas log masuk

很方便,同样的功能,代码的可读性却提高了不少,繁琐的设定也都能交给语法自动帮你完成。不过方便的语法背后,底层仍然是对象原型及原型链。

总结

以上是 JavaScript 中关于对象原型的说明,希望能帮你理解对象原型,在这个什么都是对象的语言中,充分理解并掌握对象原型,是成为专业码农必须要突破的关卡之一。

更多编程相关知识,请访问:编程课程!!

Atas ialah kandungan terperinci 了解JavaScript中的对象原型和原型链. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana untuk melaksanakan sistem pengecaman pertuturan dalam talian menggunakan WebSocket dan JavaScript Bagaimana untuk melaksanakan sistem pengecaman pertuturan dalam talian menggunakan WebSocket dan JavaScript Dec 17, 2023 pm 02:54 PM

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian Pengenalan: Dengan perkembangan teknologi yang berterusan, teknologi pengecaman pertuturan telah menjadi bahagian penting dalam bidang kecerdasan buatan. Sistem pengecaman pertuturan dalam talian berdasarkan WebSocket dan JavaScript mempunyai ciri kependaman rendah, masa nyata dan platform merentas, dan telah menjadi penyelesaian yang digunakan secara meluas. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian.

WebSocket dan JavaScript: teknologi utama untuk melaksanakan sistem pemantauan masa nyata WebSocket dan JavaScript: teknologi utama untuk melaksanakan sistem pemantauan masa nyata Dec 17, 2023 pm 05:30 PM

WebSocket dan JavaScript: Teknologi utama untuk merealisasikan sistem pemantauan masa nyata Pengenalan: Dengan perkembangan pesat teknologi Internet, sistem pemantauan masa nyata telah digunakan secara meluas dalam pelbagai bidang. Salah satu teknologi utama untuk mencapai pemantauan masa nyata ialah gabungan WebSocket dan JavaScript. Artikel ini akan memperkenalkan aplikasi WebSocket dan JavaScript dalam sistem pemantauan masa nyata, memberikan contoh kod dan menerangkan prinsip pelaksanaannya secara terperinci. 1. Teknologi WebSocket

Cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata Cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata Dec 17, 2023 pm 12:09 PM

Pengenalan kepada cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata: Dengan populariti Internet dan kemajuan teknologi, semakin banyak restoran telah mula menyediakan perkhidmatan pesanan dalam talian. Untuk melaksanakan sistem pesanan dalam talian masa nyata, kami boleh menggunakan teknologi JavaScript dan WebSocket. WebSocket ialah protokol komunikasi dupleks penuh berdasarkan protokol TCP, yang boleh merealisasikan komunikasi dua hala masa nyata antara pelanggan dan pelayan. Dalam sistem pesanan dalam talian masa nyata, apabila pengguna memilih hidangan dan membuat pesanan

Bagaimana untuk melaksanakan sistem tempahan dalam talian menggunakan WebSocket dan JavaScript Bagaimana untuk melaksanakan sistem tempahan dalam talian menggunakan WebSocket dan JavaScript Dec 17, 2023 am 09:39 AM

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian Dalam era digital hari ini, semakin banyak perniagaan dan perkhidmatan perlu menyediakan fungsi tempahan dalam talian. Adalah penting untuk melaksanakan sistem tempahan dalam talian yang cekap dan masa nyata. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian dan memberikan contoh kod khusus. 1. Apakah itu WebSocket? WebSocket ialah kaedah dupleks penuh pada sambungan TCP tunggal.

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Dec 17, 2023 pm 05:13 PM

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Pengenalan: Hari ini, ketepatan ramalan cuaca sangat penting kepada kehidupan harian dan membuat keputusan. Apabila teknologi berkembang, kami boleh menyediakan ramalan cuaca yang lebih tepat dan boleh dipercayai dengan mendapatkan data cuaca dalam masa nyata. Dalam artikel ini, kita akan mempelajari cara menggunakan teknologi JavaScript dan WebSocket untuk membina sistem ramalan cuaca masa nyata yang cekap. Artikel ini akan menunjukkan proses pelaksanaan melalui contoh kod tertentu. Kami

Tutorial JavaScript Mudah: Cara Mendapatkan Kod Status HTTP Tutorial JavaScript Mudah: Cara Mendapatkan Kod Status HTTP Jan 05, 2024 pm 06:08 PM

Tutorial JavaScript: Bagaimana untuk mendapatkan kod status HTTP, contoh kod khusus diperlukan: Dalam pembangunan web, interaksi data dengan pelayan sering terlibat. Apabila berkomunikasi dengan pelayan, kami selalunya perlu mendapatkan kod status HTTP yang dikembalikan untuk menentukan sama ada operasi itu berjaya dan melaksanakan pemprosesan yang sepadan berdasarkan kod status yang berbeza. Artikel ini akan mengajar anda cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan menyediakan beberapa contoh kod praktikal. Menggunakan XMLHttpRequest

Bagaimana untuk menggunakan insertBefore dalam javascript Bagaimana untuk menggunakan insertBefore dalam javascript Nov 24, 2023 am 11:56 AM

Penggunaan: Dalam JavaScript, kaedah insertBefore() digunakan untuk memasukkan nod baharu dalam pepohon DOM. Kaedah ini memerlukan dua parameter: nod baharu untuk dimasukkan dan nod rujukan (iaitu nod di mana nod baharu akan dimasukkan).

Bagaimana untuk mendapatkan kod status HTTP dalam JavaScript dengan cara yang mudah Bagaimana untuk mendapatkan kod status HTTP dalam JavaScript dengan cara yang mudah Jan 05, 2024 pm 01:37 PM

Pengenalan kepada kaedah mendapatkan kod status HTTP dalam JavaScript: Dalam pembangunan bahagian hadapan, kita selalunya perlu berurusan dengan interaksi dengan antara muka bahagian belakang, dan kod status HTTP adalah bahagian yang sangat penting daripadanya. Memahami dan mendapatkan kod status HTTP membantu kami mengendalikan data yang dikembalikan oleh antara muka dengan lebih baik. Artikel ini akan memperkenalkan cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan memberikan contoh kod khusus. 1. Apakah kod status HTTP bermakna kod status HTTP apabila penyemak imbas memulakan permintaan kepada pelayan, perkhidmatan tersebut

See all articles