<font id="zqva1"></font>
<rt id="zqva1"></rt>
  • <tt id="zqva1"></tt>
    <cite id="zqva1"></cite>

    <cite id="zqva1"><noscript id="zqva1"></noscript></cite>
      <rp id="zqva1"><meter id="zqva1"></meter></rp>

        <cite id="zqva1"></cite>
          <b id="zqva1"></b>
          <rp id="zqva1"></rp>
          <cite id="zqva1"></cite>

          <rt id="zqva1"></rt>

        1. <rp id="zqva1"></rp>

          js原型鏈,Javascript重溫OOP之原型與原型鏈

          時間:?2017-11-03閱讀:?852標簽:?js知識作者:?Allin_Lin

          面向對象程序設計(Object-oriented programming,OOP)是一種程序設計范型,同時也是一種程序開發的方法。對象指的是類的實例。它將對象作為程序的基本單元,將程序和數據封裝其中,以提高軟件的重用性、靈活性和擴展性。——維基百科

          一般面向對象包含:繼承,封裝,多態,抽象

          對象形式的繼承

          淺拷貝

          var Person = {
              name: 'allin',
              age: 18,
              address: {
                  home: 'home',
                  office: 'office',
              }
              sclools: ['x','z'],
          };
          
          var programer = {
              language: 'js',
          };
          
          function extend(p, c){
              var c = c || {};
              for( var prop in p){
                  c[prop] = p[prop];
              }
          }
          extend(Person, programer);
          programer.name;  // allin
          programer.address.home;  // home
          programer.address.home = 'house';  //house
          Person.address.home;  // house

          從上面的結果看出,淺拷貝的缺陷在于修改了子對象中引用類型的值,會影響到父對象中的值,因為在淺拷貝中對引用類型的拷貝只是拷貝了地址,指向了內存中同一個副本。

          深拷貝

          function extendDeeply(p, c){
              var c = c || {};
              for (var prop in p){
                  if(typeof p[prop] === "object"){
                      c[prop] = (p[prop].constructor === Array)?[]:{};
                      extendDeeply(p[prop], c[prop]);
                  }else{
                      c[prop] = p[prop];
                  }
              }
          }

          利用遞歸進行深拷貝,這樣子對象的修改就不會影響到父對象。

          extendDeeply(Person, programer);
          programer.address.home = 'allin';
          Person.address.home; // home

          利用call和apply繼承

          function Parent(){
              this.name = "abc";
              this.address = {home: "home"};
          }
          function Child(){
              Parent.call(this);
              this.language = "js"; 
          }

          ES5中的Object.create()

          var p = { name : 'allin'};
          var obj = Object.create(o);
          obj.name; // allin

          Object.create()作為new操作符的替代方案是ES5之后才出來的。我們也可以自己模擬該方法:

          //模擬Object.create()方法
          function myCreate(o){
              function F(){};
              F.prototype = o;
              o = new F();
              return o;
          }
          var p = { name : 'allin'};
          var obj = myCreate(o);
          obj.name; // allin

          目前,各大瀏覽器的最新版本(包括IE9)都部署了這個方法。如果遇到老式瀏覽器,可以用下面的代碼自行部署。

            if (!Object.create) {
              Object.create = function (o) {
                 function F() {}
                F.prototype = o;
                return new F();
              };
            }

          類的繼承

          Object.create()

          function Person(name, age){}
          Person.prototype.headCount = 1;
          Person.prototype.eat = function(){
              console.log('eating...');
          }
          function Programmer(name, age, title){}
          
          Programmer.prototype = Object.create(Person.prototype); //建立繼承關系
          Programmer.prototype.constructor = Programmer;  // 修改constructor的指向

          調用父類方法

          function Person(name, age){
              this.name = name;
              this.age = age;
          }
          Person.prototype.headCount = 1;
          Person.prototype.eat = function(){
              console.log('eating...');
          }
          
          function Programmer(name, age, title){
              Person.apply(this, arguments); // 調用父類的構造器
          }
          
          
          Programmer.prototype = Object.create(Person.prototype);
          Programmer.prototype.constructor = Programmer;
          
          Programmer.prototype.language = "js";
          Programmer.prototype.work = function(){
              console.log('i am working code in '+ this.language);
              Person.prototype.eat.apply(this, arguments); // 調用父類上的方法
          }

          封裝

          命名空間

          js是沒有命名空間的,因此可以用對象模擬。

          var app = {};  // 命名空間app
          //模塊1
          app.module1 = {
              name: 'allin',
              f: function(){
                  console.log('hi robot');
              }
          };
          app.module1.name; // "allin"
          app.module1.f();  // hi robot

          靜態成員

          function Person(name){
              var age = 100;
              this.name = name;
          }
          //靜態成員
          Person.walk = function(){
              console.log('static');
          };
          Person.walk();  // static

          私有與公有

          function Person(id){
              // 私有屬性與方法
              var name = 'allin';
              var work = function(){
                  console.log(this.id);
              };
              //公有屬性與方法
              this.id = id;
              this.say = function(){
                  console.log('say hello');
                  work.call(this);
              };
          };
          var p1 = new Person(123);
          p1.name; // undefined
          p1.id;  // 123
          p1.say();  // say hello 123

          模塊化

          var moduleA;
          moduleA = function() {
              var prop = 1;
          
              function func() {}
          
              return {
                  func: func,
                  prop: prop
              };
          }(); // 立即執行匿名函數

          prop,func 不會被泄露到全局作用域。或者另一種寫法,使用 new

          moduleA = new function() {
              var prop = 1;
          
              function func() {}
          
              this.func = func;
              this.prop = prop;
          }

          多態

          模擬方法重載

          arguments屬性可以取得函數調用的實參個數,可以利用這一點模擬方法的重載。

          function demo(a, b ){
              console.log(demo.length); // 得到形參個數
              console.log(arguments.length); //得到實參個數
              console.log(arguments[0]);  // 第一個實參 4
              console.log(arguments[1]);  // 第二個實參 5
          }
          
          demo(4, 5, 6);
          //實現可變長度實參的相加
          function add(){
              var total = 0;
              for( var i = arguments.length - 1; i >= 0; i--){
                  total += arguments[i];
              }
              return total;
          }
          
          console.log(add(1));  // 1
          console.log(add(1, 2, 3));  // 7
          
          
          // 參數不同的情況
          function fontSize(){
              var ele = document.getElementById('js');
              if(arguments.length == 0){
                  return ele.style.fontSize;
              }else{
                  ele.style.fontSize = arguments[0];
              }
          }
          fontSize(18);
          console.log(fontSize());
          
          // 類型不同的情況
          function setting(){
              var ele = document.getElementById('js');
              if(typeof arguments[0] === "object"){
                  for(var p in arguments[0]){
                      ele.style[p] = arguments[0][p];
                  }
              }else{
                  ele.style.fontSize = arguments[0];
                  ele.style.backgroundColor = arguments[1];
              }
          }
          setting(18, 'red');
          setting({fontSize:20, backgroundColor: 'green'});

          方法重寫

          function F(){}
          var f = new F();
          F.prototype.run = function(){
              console.log('F');
          }
          f.run(); // F
          
          f.run = function(){
              console.log('fff');
          }
          f.run();  // fff

          抽象類

          在構造器throw new Error('');中拋異常。這樣防止這個類被直接調用。

          function DetectorBase() {
              throw new Error('Abstract class can not be invoked directly!');
          }
          
          DetectorBase.prototype.detect = function() {
              console.log('Detection starting...');
          };
          DetectorBase.prototype.stop = function() {
              console.log('Detection stopped.');
          };
          DetectorBase.prototype.init = function() {
              throw new Error('Error');
          };
          
          // var d = new DetectorBase();// Uncaught Error: Abstract class can not be invoked directly!
          
          function LinkDetector() {}
          LinkDetector.prototype = Object.create(DetectorBase.prototype);
          LinkDetector.prototype.constructor = LinkDetector;
          
          var l = new LinkDetector();
          console.log(l); //LinkDetector {}__proto__: LinkDetector
          l.detect(); //Detection starting...
          l.init(); //Uncaught Error: Error

          轉載地址:http://www.jianshu.com/p/ac3e6c88987a

          站長推薦

          1.阿里云: 本站目前使用的是阿里云主機,安全/可靠/穩定。點擊領取2000元代金券、了解最新阿里云產品的各種優惠活動點擊進入

          2.騰訊云: 提供云服務器、云數據庫、云存儲、視頻與CDN、域名等服務。騰訊云各類產品的最新活動,優惠券領取點擊進入

          3.廣告聯盟: 整理了目前主流的廣告聯盟平臺,如果你有流量,可以作為參考選擇適合你的平臺點擊進入

          鏈接: http://www.modern-decoration.com.cn/article/detial/49

          javascript中什么是句柄?

          一個句柄是指使用的一個唯一的整數值,即一個4字節(64位程序中為8字節)長的數值,來標識應用程序中的不同對象和同類中的不同的實例。

          javascript不可變性是什么?

          不可變性即某個變量在進行了某個操作之后,其本身沒有發生變化,比如對于字符串而言,對字符串的任何操作都會改變字符串本身的值,而是在字符串的基礎上復制出來一個然后再改變,這樣我們就說是不可變的

          為什么javascript不起作用?

          JavaScript是一種屬于網絡的腳本語言,已經被廣泛用于Web應用開發,常用來為網頁添加各式各樣的動態功能,為用戶提供更流暢美觀的瀏覽效果。通常JavaScript腳本是通過嵌入在HTML中來實現自身的功能的。

          javascript怎么判斷按鈕被點擊?

          JavaScript可以通過Event對象的target事件或srcElement(IE瀏覽器支持)來判斷按鈕是否被點擊。Event對象代表事件的狀態,比如事件在其中發生的元素、鍵盤按鍵的狀態、鼠標的位置、鼠標按鈕的狀態。

          javascript由幾部分組成?

          JavaScript有三部分組成。分別為核心(ECMAScript) 、文檔對象模型(DOM)、瀏覽器對象模型(BOM)。這三部分分別描述了該語言的語法和基本對象、處理網頁內容的方法和接口、與瀏覽器進行交互的方法和接口。

          Js輸出方式有哪些?

          在編寫JavaScript代碼的時候, 一定要記住每一句代碼后面都需要添加一個分號, 并且這個分號必須是英文的分號,我們會發現有時候不寫分號程序也能夠運行, 這里并不是因為不需要分號, 而是瀏覽器自動幫助我們添加了分號

          7個常見的 JavaScript 測驗及解答

          我相信學習新事物并評估我們所知的東西對自己的進步非常有用,可以避免了我們覺得自己的知識過時的情況。在本文中,我將介紹一些常見的 JavaScript 知識。請享用!

          Js中constructor指向問題

          首先用一個例子指出來constructor存在形式。由上面的代碼我們總結出結論1:上面的代碼在控制臺可以看出constructor是指向構造器Fruit的引用。這個地方就有點奇怪了。這個constructor到底指向的是那個實例的構造器?

          javascript難點是什么?

          javascript難點是什么?下面本篇文章就來給大家介紹一下10個JavaScript難點,感興趣的小伙伴們可以參考一下,希望對大家有所幫助。立即執行函數,即Immediately Invoked Function Expression (IIFE),正如它的名字

          Js如何獲取ul中li的個數?

          javascript如何獲取ul中li的個數?下面本篇文章就來給大家介紹一下使用javascript獲取ul中li個數的方法,希望對大家有所幫助。

          內容以共享、參考、研究為目的,不存在任何商業目的。其版權屬原作者所有,如有侵權或違規,請與小編聯系!情況屬實本人將予以刪除!

          文章投稿關于web前端網站點搜索站長推薦網站地圖站長QQ:522607023

          小程序專欄: 土味情話心理測試腦筋急轉彎幽默笑話段子句子語錄成語大全運營推廣

          国产精品高清视频免费 - 视频 - 在线观看 - 影视资讯 - 唯爱网