首頁  >  文章  >  web前端  >  一文帶你去搞懂JavaScript中的原型和原型鏈

一文帶你去搞懂JavaScript中的原型和原型鏈

青灯夜游
青灯夜游轉載
2022-01-04 10:33:261778瀏覽

原型和原型鍊是JavaScript中的困難點也是重點,以下這篇文章就來帶大家去搞懂原型和原型鏈,希望對大家有幫助!

一文帶你去搞懂JavaScript中的原型和原型鏈

如果你對原型和原型鏈的了解還停留在一個很淺的、模稜兩可的階段,不妨來看看我的這篇文章,它應該能對你能有所幫助,如果對你有那麼一丟丟幫助的話,歡迎點讚評論加轉發。有問題和疑惑的話也可以在評論區留言,我會第一時間回覆大家,如果覺得我的文章哪裡有知識點錯誤的話,也懇請能夠告知,把錯的東西理解成對的,對我們這個行業來說,是致命的。

之前雖然也常刷原型方面的面試題,但是總是停留在一個很淺的、對知識點模棱兩可的階段,而且經常忘記(這點相信大夥也是這樣,哈哈哈),趁著元旦假期的最後一天(終於摸起了鍵盤),跟著b站一個影片過了下相關方面的知識,對此終於有了一個整體的理解。這裡對其進行了一個整理和歸納。

嗚嗚嗚,本猿在這裡立誓,未來一周,不管多忙,都需要回顧一遍本文,
否則
否則
掘金永遠抽bug。

先知道對應關係

prototype:原型
__proto__:原型鏈(連結點)

  • 從屬關係

    • prototype :函數的一個屬性-> 不要想的太複雜,其實就是一個普通物件{}
    • __proto__ : 物件上的一個屬性-> 不要想的太複雜,其實就是一個普通物件{}
  • 對象的__proto__保存著物件的建構子的prototype

  • 函數是特殊物件所以__proto__在函數上也是存在的,且是個function

大家常常忽略忘記的一點:Object是個方法(建構子),new Object 是個實例物件! ! !

console.log(Object) //typeof Object ==='function'
console.log(new Object) //typeof new Object ==='object'

constructor

constructor就是實例化物件的建構子

//test.constructor -> 实例化test对象的构造函数 Test
console.log(test.constructor===Test) //true

//这里个人理解为永无止境的自身调用自身,求解,没找到相关文章。
console.log(test.constructor.prototype.constructor===Test) //true
console.log(test.constructor.prototype.constructor.prototype.constructor===Test) //true
//constructor允许更改
function Test2() {
    this.a=123
}
test.constructor=Test2
console.log(test)

原型

function Test(){}
let test=new Test() //new完之后 test是个实例对象了
console.log(test.__proto__===Test.prototype) //根据上面的对应关系表 可以知道结果为true
//Test.prototype也是一个对象,所以他必须也得有__proto__
//Test.prototype.__proto__已经到达终点了,终点是什么,终点就是Object构造函数,所以下面结果为ture
console.log(Test.prototype.__proto__.constructor===Object)
//且 按照上面对应关系中的规则和上条的结果,下条结果也是ture
console.log(Test.prototype.__proto__===Object.prototype) // 
//终点为null
console.log(Object.prototype.__proto__) //null

一文帶你去搞懂JavaScript中的原型和原型鏈

#能不能描述一下原型鏈

對象的__proto__保存著對象的建構函數的prototypeprototype又是個對象,所以也有自己的__proto__,這樣往復到終點Object.__proto__,這樣就形成了一個以__proto__為連結點(為key )值為建構方法的prototype物件的一條鏈條, 即為原型鏈。

//__proto__
test{
      b:333,
      a:1,
      __proto__:Test.prototype={
          c:222,
          b:2,
          __proto__:Object.prototype={
              c:3,
              __proto__:null
          }
      }
 }

一文帶你去搞懂JavaScript中的原型和原型鏈

特殊的函數物件

重點:JS中,函數是一種特殊的物件! ! !

記住文章開頭的對應關係表

//函数是特殊对象 所以__proto__是存在的,且是个function
console.log(Test.__proto__) //function
console.log(Test.prototype) //object

Test既然是個函數,那麼底層必然也是new Function實現的,那麼

//对象的__proto__保存着对象的构造函数的prototype
console.log(Test.__proto__===Function.prototype) //true 这里是不是和关系表对应上了,能正常理解

const obj={}
const obj2=new Object()

console.log(Object) //function
console.log(typeof Object) //'function'

Function既然是個建構函數,那麼他是否也應該有__proto__prototype,是的,但這裡有一個特殊的點需要記住。

底層規則規定:Function.__proto__===Function.prototype是相等的,且兩者回傳的都是一個function,我的理解是Function自己構造了自己。

//正常来说函数的Test.prototype应该是个object,
//Function.prototype是个function,这也是一个特殊的点
typeof Test.prototype==='object' //true

console.log(Function.__proto__) // 一个function
console.log(Function.prototype) // 一个function
//Function既然是函数对象_,那么他的_proto__就指向他的构造函数的prototype,也就是
//Function.__proto__===Function.prototype,自己调自己,这样理解是不是也没毛病。
console.log(Function.__proto__===Function.prototype) //true

//Object既然是个构造方法,那么底层也是new Function
console.log(Object.__proto__===Function.prototype) //true

// 因为Function.__proto__===Function.prototype 所以下面代码是成立的
(Object.__proto__===Function.__proto__)===true

hasOwnProperty和in

hasOwnProperty

hasOwnProperty用來判斷是否是物件本身的屬性(非原型鏈繼承過來的)

let test={
    a:1,
    b:2
}
Object.prototype.c=3
console.log(test.hasOwnProperty('a')) //true
console.log(test.hasOwnProperty('b')) //true
console.log(test.hasOwnProperty('c')) //false

in

#in用來檢查物件是是否包含某個屬性(包含原型鏈上的屬性)

console.log('a' in test) //true
console.log('b' in test) //true
console.log('c' in test) //true
console.log('toString' in test) //true
console.log('d' in test) //false

【相關推薦:javascript學習教學

以上是一文帶你去搞懂JavaScript中的原型和原型鏈的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除