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

歡迎訪問 生活随笔!

生活随笔

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

javascript

JavaScript --- [学习笔记] 原型模式

發布時間:2023/12/10 javascript 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript --- [学习笔记] 原型模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

說明

  • 接JavaScript — > [學習筆記]觀察者模式 & 理解對象 & 工廠模式 & 構造函數模式
  • 上一篇構造函數模式創建的實例,不同實例的同一個方法是不相等的,為了解決這個問題.出現了原型模式

1. 原型模式

  • 具體做法是,不在構造函數中定義對象實例的信息,而是將這些信息直接添加到原型對象中
function Person(){} Person.prototype.name ="Nicholas"; Person.prototype.age =29; Person.prototype.job ="Software Engineer"; Person.prototype.sayName = function () {alert(this.name); }; var person1 = new Person(); person1.sayName(); // "Nicholas"var person2 = new Person(); person2.sayName(); // "Nicholas"console.log(person1.sayName == person2.sayName); // true

1.1 理解原型對象

1.1.1 prototype屬性和constructor屬性

  • 創建一個函數(Person),就會根據一組規則創建一個prototype屬性(Person.prototype)
  • prototype上面還要一個constructor屬性(必帶技能),它(Person.prototype.constructor)指向函數Person
  • prototype屬性上的所有屬性和方法會被所有使用new操作符生產的實例(person1, person2)共享
  • 實例person1、person2通過new Person得到,會有一個[[Prototype]]的指針(在瀏覽器中通過__proto__訪問),它指向Person.prototype

1.1.2 讀取某個屬性的順序

  • 讀取屬性的模擬函數如下:
// obj是某個對象, attr是該對象的屬性 const getVal = (obj, attr) =>{// 如果對象中存在該屬性則返回if(obj[attr]) {return obj[attr]} else if (obj.constructor === Object) {// 是Objectreturn undefined} else{// 不是Object,檢查其constructor指向的函數if(obj.constructor[attr]){return obj.constructor[attr]} else {// constructor指向的函數中不存在,順著 __proto__ 屬性找下去.getVal(obj.__proto__, attr);}} }

說明:

  • 所有通過function聲明的函數,都繼承自Function
  • Function繼承自Object
  • 1.1.3 說說

    通過上面的原型找屬性的順序,可以知道:

  • 當使用new Person生成實例(person1)的時候,person1會有一個指向Person.prototype的指針__proto__
  • 當訪問person1的屬性或方法的時候,先從實例開始尋找,若找到了則返回,否則會順著__proto__向上尋找

  • 1.2 區分一個屬性是否來自原型

    需要明白下面2點:

  • 使用in操作符會返回所有對象上的屬性或者方法
  • 使用hasOwnProperty可以確定一個屬性是否來自實例對象
  • // 判斷一個熟悉是否來自原型 const fromPrototype = (obj, attr) {return !obj.hasOwnprototype && (attr in obj); }

    1.3 Object.defineProperty

    • Object.defineProperty: 可以給一個對象添加屬性,并對屬性進行描述
    • 使用如下:
    Object.defineProperty(Person.prototype, "constructor", {enumerable: false,value: Person })

    1.3.1 數據屬性和訪問器屬性

  • JS中的屬性類型分為: 數據屬性和訪問器屬性
  • 數據屬性包括:
    • [[Configurabal]]: 是否能被delete刪除
    • [[Numerable]]: 是否能被for-in循環訪問屬性
    • [[Writeble]]: 是否可以被修改
    • [[Value]]: 屬性的值
  • 訪問器屬性: Configurable、Numerable、Get(讀取時觸發) 、Set(修改時觸發)
  • 1.3.2 Object.defineProperty的使用

    • 在使用對象字面量對函數的原型進行賦值的時候,會丟失原本的constructor屬性
    • 使用Object.defineProperty為它加上constructor屬性
    function Person () {} Person.prototype = {name: 'marron',age: 18 } Object.defineProperty(Person.prototype, constructor, {numerable: false,value: Person })
  • constructor是不能被for-in循環訪問到的
  • 在字面量中直接賦值,會被for-in循環訪問到
  • 1.4 原型的動態性

    • 可以先創建實例后修改原型
    function Person () {}; cosnt friend = new Person(); Person.prototype.sayHi = () => { console.log('SayHi') }; friend.sayHi();
    • 將上述代碼修改為下面:
    - Person.prototype.sayHi = () => { console.log('SayHi') }; + Person.prototype = { + sayHi: function () { + console.log('SayHi'); + } + }
    • 此時在調用friend.sayHi會報錯: Uncaught TypeError: p1.sayHi is not a function, 原因如下:
  • 使用new操作符時: 建立了一個指針 proto, 它指向 Person.prototype(這個是默認建立的),假設在空間A中,即此時 person1 先從自己的空間中取數據,若沒有則去 A中找
  • 當對Person.prototype進行字面量賦值時, 它改變的是Person.prototype指針的指向,在上面的一系列操作實際是在空間B中.
  • 當完成了Person.prototype的字面量賦值后,相當于給Person的原型對象新開辟了一個空間B.而此時person1的__proto__還是指向A.故訪問不到B
  • 注:重寫原型對象切斷了現有原型與任何之前已經存在的對象實例之間的聯系.

    總結

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

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