<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      javascript中new關鍵字詳解

      和其他高級語言一樣 javascript 中也有 new 運算符,我們知道 new 運算符是用來實例化一個類,從而在內存中分配一個實例對象。 但在 javascript 中,萬物皆對象,為什么還要通過 new 來產生對象? 本文將帶你一起來探索 javascript 中 new 的奧秘...

      一、認識new運算符:

      function Animal(name){
              this.name = name;
          }
          Animal.color = "black";
          Animal.prototype.say = function(){
              console.log("I'm " + this.name);
          };
          var cat = new Animal("cat");
      
          console.log(
             cat.name,  //cat
             cat.height //undefined
          );
          cat.say(); //I'm cat
      
          console.log(
             Animal.name, //Animal
             Animal.color //back
          );
          Animal.say(); //Animal.say is not a function

      如果你能理解上面輸出的結果,說明你已非常了解js中new和this的運行機制,請忽略本文!

      我們將通過解析這個例子來加深你對js中new運算符的理解! 【如果你對js的this還不了解,請先閱讀:JS作用域和this關鍵字

      1、代碼解讀

        1-3行創建了一個函數Animal,并在其this上定義了屬性:name,name的值是函數被執行時的形參。

        第4行在Animal對象(Animal本身是一個函數對象)上定義了一個靜態屬性:color,并賦值“black”

        5-7行在Animal函數的原型對象prototype上定義了一個say()方法,say方法輸出了this的name值。

        第8行通過new關鍵字創建了一個新對象cat

        10-14行cat對象嘗試訪問name和color屬性,并調用say方法。

        16-20行Animal對象嘗試訪問name和color屬性,并調用say方法。

      2、重點解析

        第8行代碼是關鍵:

       var cat = new Animal("cat"); 

      JS引擎執行這句代碼時,在內部做了很多工作,用偽代碼模擬其工作流程如下:

      new Animal("cat") = {
      
          var obj = {};
      
          obj.__proto__ = Animal.prototype;
      
          var result = Animal.call(obj,"cat");
      
          return typeof result === 'object'? result : obj;
      }

      (1)創建一個空對象obj;

      (2)把obj的__proto__ 指向Animal的原型對象prototype,此時便建立了obj對象的原型鏈:obj->Animal.prototype->Object.prototype->null

            【如果你不了解JS原型鏈,請先閱讀:JS原型和原型鏈

      (3)在obj對象的執行環境調用Animal函數并傳遞參數“cat”。 相當于var result = obj.Animal("cat")。

             當這句執行完之后,obj便產生了屬性name并賦值為"cat"。【關于JS中call的用法請閱讀:JS的call和apply

      (4)考察第3步返回的返回值,如果無返回值或者返回一個非對象值,則將obj返回作為新對象;否則會將返回值作為新對象返回。

       

      理解new的運行機制以后,我們知道cat其實就是過程(4)的返回值,因此我們對cat對象的認知就多了一些:

      cat的原型鏈是:cat->Animal.prototype->Object.prototype->null

      cat上新增了一個屬性:name

      分析完了cat的產生過程,我們再看看輸出結果:

      cat.name -> 在過程(3)中,obj對象就產生了name屬性。因此cat.name就是這里的obj.name

      cat.color -> cat會先查找自身的color,沒有找到便會沿著原型鏈查找,在上述例子中,我們僅在Animal對象上定義了color,并沒有在其原型鏈上定義,因此找不到。

      cat.say -> cat會先查找自身的say方法,沒有找到便會沿著原型鏈查找,在上述例子中,我們在Animal的prototype上定義了say,因此在原型鏈上找到了say方法。

      另外,在say方法中還訪問this.name,這里的this指的是其調用者obj,因此輸出的是obj.name的值。

      對于Animal來說,它本身也是一個對象,因此,它在訪問屬性和方法時也遵守上述查找規則,所以:

      Animal.color -> "black"

      Animal.name -> "Animal" , Animal先查找自身的name,找到了name,注意:但這個name不是我們定義的name,而是函數對象內置的屬性。

      一般情況下,函數對象在產生時會內置name屬性并將函數名作為賦值(僅函數對象)。

      Animal.say -> Animal在自身沒有找到say方法,也會沿著其原型鏈查找,話說Animal的原型鏈是什么呢?

       從測試結果看:Animal的原型鏈是這樣的:

       Animal->Function.prototype->Object.prototype->null

       因此Animal的原型鏈上沒有定義say方法!

       

      二、new存在的意義

      認識了new運算符之后,我們再回到開篇提到的問題:JS中萬物皆對象,為什么還要通過new來產生對象?要弄明白這個問題,我們首先要搞清楚cat和Animal的關系。

      通過上面的分析,我們發現cat繼承了Animal中的部分屬性,因此我們可以簡單的理解:Animal和cat是繼承關系。

      另一方面,cat是通過new產生的對象,那么cat到底是不是Animal的實例對象? 我們先來了解一下JS是如何來定義“實例對象”的?

       A instanceof B 

      如果上述表達式為true,JS認為A是B的實例對象,我們用這個方法來判斷一下cat和Animal

       cat instanceof Animal; //true 

      從執行結果看:cat確實是Animal實例,要想證實這個結果,我們再來了解一下JS中instanceof的判斷規則:

        var L = A.__proto__; var R = B.prototype; if(L === R) return true; 

      如果A的__proto__ 等價于 B的prototype,就返回true

      在new的執行過程(2)中,cat的__proto__指向了Animal的prototype,所以cat和Animal符合instanceof的判斷結果。因此,我們認為:cat是Animal的實例對象。

       

      javascript 使用new關鍵字的區別

      第一種方式使用new關鍵字以原型的方式將user對象暴露到window對象中

      //one
      var user = function(){
        this.name="";
        this.id="";
      };
      user.add = function(){
        console.log("add");
      };
      user.delete = function(){
        console.log("delete");
      };
      user.prototype = user;
      window.user = new user();
       

      第二種方式不使用new關鍵字直接將user對象暴露到window對象中

      //two
      var user = {
        name:"",
        id:""
      };
      user.add = function(){
        console.log("add");
      };
      user.delete = function(){
        console.log("delete");
      };
      window.user = user;

      使用

      <button onclick="user.add()">增加</button>
      <button onclick="user.delete()">刪除</button>

       

       

      簡單的總結語

      在javascript中, 通過new可以產生原對象的一個實例對象,而這個實例對象繼承了原對象的屬性和方法。因此,new存在的意義在于它實現了javascript中的繼承,而不僅僅是實例化了一個對象!

      文章引用至:

      http://www.rzrgm.cn/onepixel/p/5043523.html

      http://www.jb51.net/article/76362.htm

      posted @ 2017-03-10 10:52  AaronHuang  閱讀(32253)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 天堂在/线中文在线资源 官网| 免费无码成人AV在线播放不卡| 国产精品一区二区久久精品 | 久久一日本道色综合久久| 久久国产免费观看精品3| 亚洲va韩国va欧美va| 国产粉嫩一区二区三区av| 国产一区二区日韩在线| 777奇米四色成人影视色区| 少妇无套内射中出视频| 亚洲色大成网站WWW永久麻豆| 国产强奷在线播放免费| 日日噜噜夜夜狠狠视频| 日韩一区二区三区理伦片 | 国产一区二区三区精品自拍| 3d无码纯肉动漫在线观看| 综合色一色综合久久网| 色偷一区国产精品| 国产jlzzjlzz视频免费看| 成人欧美一区二区三区在线观看| 欧美性猛交xxxx乱大交丰满| 日韩免费码中文在线观看| 高清中文字幕一区二区| 99在线精品国自产拍中文字幕| 国产在线视频精品视频| 久久久久久久久久久久中文字幕 | 免费黄色大全一区二区三区| 日本韩国一区二区精品| 铜川市| 国产午夜亚洲精品福利| 亚洲高清aⅴ日本欧美视频| 97午夜理论电影影院| 欧美性做爰片免费视频看| 久章草这里只有精品| 蜜臀av午夜精品福利| 台北市| 精品中文人妻中文字幕| 国产一区二区三区美女| 国产高清在线精品一区不卡| 久久99精品久久久久久青青| 精品人妻一区二区三区四区在线|