__proto__ prototypeとどこに現れますか?それらの間にはどんな関係がありますか?継承を実現するには何に依存しますか?


再帰、閉パッケージ、プロトタイプ、継承


本文は主にいくつかの関数のよく使う知識点を説明して、整理します:再帰、閉包は何ですか、閉包の使用シーン、何が原型と原型チェーンですか、どのように継承、継承の原理を実現しますか、原文.

再帰


関数の再帰は、関数で自身を呼び出すことです.
例を挙げると、有名なフィボナッチ数列がどのように求められているのか、問題はこうです.
  • 最初の月の初めに誕生したばかりのウサギが
  • 匹いました
  • の2ヶ月目以降(3ヶ月目)
  • を出産することができます
  • 毎月産むことができるウサギのペアごとに次の新しいウサギが誕生します
  • ウサギは死なない
  • 定義された数列は
    n月にどれだけのウサギがいるかを求め、再帰アルゴリズムで求めることができます.
    function fn(n) {
      return n < 2 ? 1 : fn(n - 1) + fn(n - 2)
    }
    var count = fn(30);
    console.log(count);

    クローズドパッケージ


    閉鎖とは何ですか.閉パッケージは、宣言された関数の役割ドメイン内の変数を継承してアクセスできる関数です.
    function fn1 () {
      var a = 'hello'
      function fn2 () {
        console.log(a)
      }
    }
    fn1() //    fn2       

    クローズドパッケージの使用シーン


    クローズド・パッケージには使用シーンがたくさんあります.次に例を示します.
    1.プライベート変数
    function Person(){    
      var name = "default";       
      return {    
        getName : function(){    
          return name;    
        },    
          setName : function(newName){    
          name = newName;    
        }    
      }    
    };
    var person = Person()
    console.log(person.getName()) // default
    person.setName('xiaomuchen')
    console.log(person.getName()) // xiaomuchen
    var person2 = Person()
    console.log(person2.getName()) // default

    上記の関数は、閉パケットを使用してプライベート変数nameを作成し、変数は外部で直接操作、取得できず、返されるインタフェースでしか制御できません.
    2.匿名自己実行関数
    たとえば、ページを開発するときにページを初期化する必要がある場合は、すぐにいくつかの操作を行う必要があります.ページでは を使用して、JSエンジンがこのコードを読み込んだときにすぐに実行できます.
    //   title          
    (function(){
      var openTime = new Date()
      document.title = document.title + openTime
    })();  

    プロトタイプ、プロトタイプチェーン、継承


    まず質問です:_proto__ prototypeとどこに現れますか?それらの間にはどんな関係がありますか?継承を実現するには何に依存しますか?
    __proto__ prototypeとの違い
    1.JavaScriptの各オブジェクトにはプロトタイプチェーンがあります(_proto_)そのコンストラクション関数を指すプロトタイプ(prototype)
    var a = {}
    a.__proto__ === Object.prototype // true
    
    function Person () {}
    Person.__proto__ === Function.prototype // true
    
    var p = new Person()
    p.__proto__ === Person.prototype // true

    2.JavaScriptの各関数にはプロトタイプ(prototype)があり、プロトタイプもオブジェクトである.このオブジェクトには、プロトタイプチェーン、プロトタイプメソッド(属性)、関数構造が含まれ、そのプロトタイプチェーンはその構築関数のプロトタイプを指す.
    function Person () {}
    Person.prototype.getName = function () {}
    Object.getOwnPropertyNames(Person.prototype) // ["constructor", "getName"]
    Person.prototype.__proto__ === Object.prototype // true

    3.関数上の属性にアクセスする場合、.オブジェクトのプロパティにアクセスすると、になります.ない場合は、Objectにアクセスするまで、プロトタイプ上のプロトタイプチェーンを介して上を検索し続けます.prototypeのプロパティは、まだない場合はObjectのためです.prototypeはありません_proto__ のオブジェクトを検索すると、クエリーはここまででundefinedを返します.
    function Person () {}
    Person.getName = function () {
      console.log('Person1')
    }
    Person.prototype.getName = function () {
      console.log('Person2')
    }
    var p = new Person()
    
    Person.getName() // Person1
    p.getName() // Person2
    console.log(typeof p.getClass) // undefined

    継承
    JavaScript関数は、プロトタイプとプロトタイプチェーンによって継承されます.
    function superA (name) {
      this.name = name
    }
    superA.prototype.getName = function () {
      console.log(this.name)
    }
    function subA (name) {
      superA.call(this, name) //     
    }
    subA.prototype = new superA() //     
    
    var a1 = new subA('xiaomuchen')
    a1.getName() // xiaomuchen

    上記のコードは、関数の古典的な継承を記述し、その動作原理は次のとおりです.
  • 親superA、子subA
  • を宣言
  • サブクラスsubAのプロトタイプを書き換え、superAのインスタンス
  • を指す.
  • a 1をインスタンス化すると、a 1._proto__ => subA.prototype => new superA() => superA.prototypeですから、a 1の構造関数はsuperA
  • です.
  • 同時にsubAすなわちsuperAを実行する.call(this,'xiaomuchen')は、thisがa 1を指すため、a 1はname属性
  • を継承する
  • のようなsubAの例a 1はsuperAのプロトタイプメソッドと属性
  • を継承する.

    まとめ


    本文は再帰、閉包、原型、継承を概括し、これらの基本的な概念を整理し、より多くのものを受け入れるのに役立ち、次の章で関数をより深く議論します.
    作者:肖沐宸,github.