日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JavaScript 原型 原型链

發布時間:2024/3/12 javascript 59 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript 原型 原型链 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JavaScript 原型

本文講介紹JavaScript原型 以及JavaScript的原型鏈


JS中的原型和原型鏈


所有的引用類型(數組、函數、對象)可以自由擴展屬性(除null以外)

所有的函數都有一個prototype屬性(顯式原型)

所有的引用類型都有一個__proto__屬性(隱式原型)

所有引用類型 它的__proto__屬性指向它的構造函數的 prototype屬性

當試圖得到一個對象的屬性時 如果這個對象不存在這個屬性,那么就會去它的 __ proto__的路線去查找 也就是構造函數中的 prototype 中去查找


一、原型的使用和原型的概念

1.顯式原型 prototype

在我們創建一個函數的時候 每個函數都會有一個prototype(原型)屬性 這個屬性指向一個對象,這個對象包含著可以實例共享的屬性和方法 你可以不必再構造函數中定義對象的實例信息 而直接將這些信息直接添加到原型對象中

// ↓ -------- 創建一個構造函數 --------function Person(name,age) {this.name = name;this.age = age;}Person.prototype.sex = "man" // ↓ -------- 在原型中添加一條方法 ---------Person.prototype.seyLove = function () {console.log(name +" love 1024")}; // ↓ -------- 實例化這個對象 ----------var man = new Person("伊凡ED",20);console.log(man)console.log(man.name+" sex="+man.sex);Person.prototype.seyLove()// - ↑ 輸出結果 = Person?{name: "伊凡ED", age: 20} // 伊凡FD sex=man // love 1024

如果我們再構造函數內定義好這個seyLove方法的話 那么我們用這個構造函數構造的每一個對象里都會擁有seyLove這個方法 這樣我們就浪費了很多的資源 我們完全可以給需要用到的對象添加需要的方法? 那么 我們就可以用原型方法 并且這個方法可以繼承 需要了解繼承可以在我的博客搜索 JavaScript 繼承


2.隱式原型(原型對象)__proto__

JavaScript中的所有對象(除了null)都具有的一個屬性 __proto__ 所有的__proto__都是指向它的構造函數的 prototype 屬性 下面的例子最后一行也向我們證明了這一點?

// ↓ -------- 創建一個構造函數 --------function Person(name,age) {this.name = name;this.age = age;}Person.prototype.sex = "man" // ↓ -------- 在原型中添加一條方法 ---------Person.prototype.seyLove = function () {console.log(name +" love 1024")}; // ↓ -------- 實例化這個對象 ----------var man = new Person("伊凡ED",20);console.log(man)console.log(man.name+" sex="+man.sex);Person.prototype.seyLove()console.log(man.__proto__)console.log(Person.prototype)console.log(man.__proto__===Person.prototype)// - ↑ 上面的代碼輸出 :Person?{name: "伊凡FD", age: 20} // 伊凡ED sex=man // love 1024 // {sex: "man", seyLove: ?, constructor: ?} // {sex: "man", seyLove: ?, constructor: ?} // true

我們接著用一張圖清楚的標明他的指向

3.Object

既然 剛才說所有的對象 都有一個__proto__屬性 那么我們原型的__proto__指向哪里呢?

// ↓ -------- 創建一個構造函數 --------function Person(name,age) {this.name = name;this.age = age;}Person.prototype.sex = "man"// ↓ -------- 在原型中添加一條方法 ---------Person.prototype.seyLove = function () {console.log(name +" love 1024")};// ↓ -------- 實例化這個對象 ----------var man = new Person("伊凡FD",20);console.log(man.__proto__.__proto__)// - ↑ 上面的輸出:/* constructor: ? Object()* hasOwnProperty: ? hasOwnProperty()* isPrototypeOf: ? isPrototypeOf()* propertyIsEnumerable: ? propertyIsEnumerable()* toLocaleString: ? toLocaleString()* toString: ? toString()* valueOf: ? valueOf()* __defineGetter__: ? __defineGetter__()* __defineSetter__: ? __defineSetter__()* __lookupGetter__: ? __lookupGetter__()* __lookupSetter__: ? __lookupSetter__()* get __proto__: ? __proto__()* set __proto__: ? __proto__()* */

得到的結果看著還很長 我們順著這條線 來到了Object構造函數的原型?

4.null

這次我們打印Object.prototype的__proto__ 輸出為null (萬物皆對象 對象皆為空)

// ↓ -------- 創建一個構造函數 --------function Person(name,age) {this.name = name;this.age = age;}Person.prototype.sex = "man"// ↓ -------- 在原型中添加一條方法 ---------Person.prototype.seyLove = function () {console.log(name +" love 1024")};// ↓ -------- 實例化這個對象 ----------var man = new Person("伊凡FD",20);console.log(man.__proto__.__proto__.__proto__)// - ↑ 上面的輸出:null

5.原型的查找屬性

現在我可以解釋一下 原型的查找屬性 根據上面的__proto__ 如果在一個對象中查找某個屬性 未查找到 則會順著__proto__的路線向上查找 也就是 先去查找顯性原型中有沒有該屬性 如果沒有 他就會沿著__proto__的路線一直向上找 也就是他會根據構造安徽函數的原型去查找 ?如果都沒又找到 最后只能輸出null 萬物皆為空

6.constructor?

以上的指針指向的都是原型 剛才也說了每一個對象都有一個__proto__ 每一個__proto__ 都指向的是原型 而每一個原型 都又一個關聯的構造函數 而constructor 就是指向這個函數的

// ↓ -------- 創建一個構造函數 --------function Person(name,age) {this.name = name;this.age = age;}Person.prototype.sex = "man"// ↓ -------- 在原型中添加一條方法 ---------Person.prototype.seyLove = function () {console.log(name +" love 1024")};// ↓ -------- 實例化這個對象 ----------var man = new Person("伊凡ED",20);console.log(man.__proto__.constructor?);console.log(man.__proto__.constructor.prototype?);console.log(man.__proto__.__proto__.constructor?);console.log(man.__proto__.__proto__.constructor.prototype?);// - ↑ 輸出結果:/* ? Person(name,age) {* this.name = name;* this.age = age;* }* {sex: "man", seyLove: ?, constructor: ?}* ? Object() { [native code] }* {constructor: ?, __defineGetter__: ?, * __defineSetter__: ?,* hasOwnProperty: ?,* __lookupGetter__: ?,* …}* */

情況如下圖:

我們在使用原型的時候 一般將需要擴展的方法寫在構造函數的prototype屬性中 避免寫在__proto__屬性里面。
?

總結

以上是生活随笔為你收集整理的JavaScript 原型 原型链的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。