Javascript高級第二天筆記

 

 

課程介紹:

重點: 原型鏈
    * 重點:不同的繼承
    * 原型的另一個作用
    * 重點:this指向要知道到底是誰
    *
    * 複習原型
    * 原型鏈
    * 原型的指向是否可以改變
    * 繼承
    * 如何實現繼承
    * 原型的方式繼承
    * 借用構造函數繼承
    * 組合繼承
    * 拷貝繼承
    *
    * 函數的不同的表現方式
    * 函數的調用的不同的方式
    *
    * this指向
    * 嚴格模式
    *
    * 函數也是對象---記住就可以了
    * 對象不一定是函數
    *
    * 數組中的函數如何調用
    * apply和call講了

03原型與原型鏈

<script>
    //使用對象---->使用對象中的屬性和對象中的方法,使用對象就要先有構造函數
    //構造函數
    function Person(name,age) {
      //屬性
      this.name=name;
      this.age=age;
      //在構造函數中的方法
      this.eat=function () {
        console.log("吃好吃的");
      };
    }
    //添加共享的屬性
    Person.prototype.sex="男";
    //添加共享的方法
    Person.prototype.sayHi=function () {
      console.log("您好啊,怎麼這麼帥,就是這麼帥");
    };
    //實例化對象,並初始化
    var per=new Person("小明",20);
    per.sayHi();
    //如果想要使用一些屬性和方法,並且屬性的值在每個對象中都是一樣的,方法在每個對象中的操作也都是一樣,那麼,爲了共享數據,節省內存空間,是可以把屬性和方法通過原型的方式進行賦值

    console.dir(per);//實例對象的結構
    console.dir(Person);//構造函數的結構

    //實例對象的原型__proto__和構造函數的原型prototype指向是相同的

    //實例對象中的__proto__原型指向的是構造函數中的原型prototype
    console.log(per.__proto__==Person.prototype);
    //實例對象中__proto__是原型,瀏覽器使用的
    //構造函數中的prototype是原型,程序員使用的

    //原型鏈:是一種關係,實例對象和原型對象之間的關係,關係是通過原型(__proto__)來聯繫的



  </script>

 圖片解析

 

 04原型的指向是否可以改變

 //人的構造函數
    function Person(age) {
      this.age=10;
    }
    //人的原型對象方法
    Person.prototype.eat=function () {
      console.log("人的吃");
    };
    //學生的構造函數
    function Student() {

    }
    Student.prototype.sayHi=function () {
      console.log("嗨,小蘇你好帥哦");
    };
    //學生的原型,指向了一個人的實例對象
    Student.prototype=new Person(10);
    var stu=new Student();
    stu.eat();----人的吃
    stu.sayHi();---會報錯,應爲學生原型指向person,person裏面沒有sayhi

    //原型指向可以改變
    //實例對象的原型__proto__指向的是該對象所在的構造函數的原型對象
    //構造函數的原型對象(prototype)指向如果改變了,實例對象的原型(__proto__)指向也會發生改變

    //原型的指向是可以改變的
    //實例對象和原型對象之間的關係是通過__proto__原型來聯繫起來的,這個關係就是原型鏈

 05原型最終指向了哪裏

function Person() {

    }
    Person.prototype.eat=function () {
      console.log("吃東西");
    };

    var per=new Person();
    console.dir(per);
    console.dir(Person);

    //實例對象中有__proto__原型
    //構造函數中有prototype原型
    //prototype是對象
    //所以,prototype這個對象中也有__proto__,那麼指向了哪裏
    //實例對象中的__proto__指向的是構造函數的prototype
    //所以,prototype這個對象中__proto__指向的應該是某個構造函數的原型prototype

    //Person的prototype中的__proto__的指向
    //console.log(Person.prototype.__proto__);

    //per實例對象的__proto__------->Person.prototype的__proto__---->Object.prototype的__proto__是null

    console.log(per.__proto__==Person.prototype);    true 
    console.log(per.__proto__.__proto__==Person.prototype.__proto__);     true
    console.log(Person.prototype.__proto__==Object.prototype);       true
    console.log(Object.prototype.__proto__);               null

 

06原型指向和如何添加方法 

function Person(age) {
				this.age=age;
			}
			//人的原型中添加方法
			Person.prototype.eat=function () {
				console.log("一方園地1在吃東西");
			};
			//學生構造函數
			function Student(sex) {
				this.sex=sex;
			}
		
			//學生的原型中添加方法----先在原型中添加方法
			Person.prototype.sayHi=function () {
				console.log("一方園地1");
			};
			
			
			//改變了原型對象的指向
			Student.prototype=new Person(10);
			Student.prototype.eat=function () {
				console.log("一方園地2在吃東西");
			};
			Student.prototype.sayHi=function () {
				console.log("一方園地2");
			};
		
			var stu=new Student("男");
			stu.eat();      //一方園地2吃東西
			stu.sayHi();    //一方園地2

下一個案例重複總結:

function Person(age) {
      this.age = age;
    }

    //指向改變了
    Person.prototype = {
      eat: function () {
        console.log("吃");
      }
    };
    //先添加原型方法
    Person.prototype.sayHi = function () {
      console.log("方園您好");
    };
    var per = new Person(10);
    per.sayHi();          

 上面運行結果是:方園,您好。分析:因爲前面雖讓指向了一個新的對象,但後面又重新更新了原型,有了新的指向。

那麼下面這樣改變一下---------->

function Person(age) {
      this.age = age;
    }

    //指向改變了,下面是個大括號,代表着一個對象。
    Person.prototype = {
      eat: function () {
        console.log("吃");
      }
    };
    //先添加原型方法
    Person.prototype.sayHi = function () {
      console.log("方園您好");
    };
		Person.prototype = {
			eat: function () {
				console.log("吃");
			}
		};
    var per = new Person(10);
    per.sayHi();

 上面結果會報錯》

爲啥會這樣?因爲指向改變了,大括號代表新的對象,代表對象改變了,之前做的原型吃是沒有用的!這句話是僅僅我自己的理解

07實例對象中的和原型對象中的屬性重名問題

首先先給你分析一下何爲屬性:看一下下面的代碼

function Person(age,sex) {
   this.age=age;
   this.sex=sex;
   }
    Person.prototype.sex="女";
    var per=new Person(10,"男");
    console.log(per.sex);//男
            
    console.log(per.fy);//undefind
        
        
   console.log(fy);  //報錯

//因爲JS是一門動態類型的語言,對象沒有什麼,只要點了,那麼這個對象就有了這個東西,沒有這個屬性,只要對象.屬性名字,(例如上面的per.fy)對象就有這個屬性了,但是,該屬性沒有賦值,所以,結果是:undefined.而沒有點,(僅僅fy)則沒有這個屬性,會報錯

function Person(age,sex) {
	  this.age=age;
	  this.sex=sex;
	}
	Person.prototype.sex="女";
	var per=new Person(10,"男");
	console.log(per.sex);
	Person.prototype.sex="一方園地";
	   per.sex="二哈";
	   console.log(per.sex);
	
	   console.dir(per);  

此處最後的的per.sex="二哈"; 代表重新更改他的屬性sex


//實例對象訪問這個屬性,應該先從實例對象中找,找到了就直接用,找不到就去指向的原型對象中找,找到了就使用,找不到呢?
//通過實例對象能否改變原型對象中的屬性值?不能
//就想改變原型對象中屬性的值,怎麼辦?直接通過原型對象.屬性=值;可以改變(就是上面的per.sex=二哈)
 


08一個很神奇的原型鏈

 原型鏈:實例對象和原型對象之間的關係,通過__proto__來聯繫

 var divObj=document.getElementById("dv");
  console.dir(divObj);

 //divObj.__proto__---->HTMLDivElement.prototype的__proto__--->HTMLElement.prototype的__proto__---->Element.prototype的__proto__---->Node.prototype的__proto__---->EventTarget.prototype的__proto__---->Object.prototype沒有__proto__,所以,Object.prototype中的__proto__是null

09繼承

* 面向對象編程思想:根據需求,分析對象,找到對象有什麼特徵和行爲,通過代碼的方式來實現需求,要想實現這個需求,就要創建對象,要想創建對象,就應該顯示有構造函數,然後通過構造函數來創建對象.,通過對象調用屬性和方法來實現相應的功能及需求,即可
* 首先JS不是一門面向對象的語言,JS是一門基於對象的語言,那麼爲什麼學習js還要學習面向對象,因爲面向對象的思想適合於人的想法,編程起來會更加的方便,及後期的維護....
* 面向對象的編程語言中有類(class)的概念(也是一種特殊的數據類型),但是JS不是面向對象的語言,所以,JS中沒有類(class),但是JS可以模擬面向對象的思想編程,JS中會通過構造函數來模擬類的概念(class)
*
*
* 小明,小紅,小麗,小白,小花 都是人
* 共同的特徵和行爲
* 特徵--->屬性
* 行爲---方法
*
* 面向對象的特性:封裝,繼承,多態
*
* 封裝:就是包裝
* 一個值存儲在一個變量中--封裝
* 一坨重複代碼放在一個函數中--封裝
* 一系列的屬性放在一個對象中--封裝
* 一些功能類似的函數(方法)放在一個對象中--封裝
* 好多相類似的對象放在一個js文件中---封裝
*
* 繼承: 首先繼承是一種關係,類(class)與類之間的關係,JS中沒有類,但是可以通過構造函數模擬類,然後通過原型來實現繼承
* 繼承也是爲了數據共享,js中的繼承也是爲了實現數據共享

*
* 原型作用之一:數據共享,節省內存空間
* 原型作用之二:爲了實現繼承
*
* 繼承是一種關係:
*
* 父類級別與類級別的關係
*
* 例子:
*
* 小楊--->人, 姓名, 有錢, 帥, 有功夫--降龍十八掌
* 小楊子-->人,
* 繼承:
* 姓氏----繼承
* 外表----繼承
* 財產----繼承
* 功夫---繼承
*
*
* 人:  姓名, 性別, 年齡 ,吃飯, 睡覺
*
* 學生類別: 姓名, 性別, 年齡 ,吃飯, 睡覺 學習行爲
* 老師類別: 姓名, 性別, 年齡 ,吃飯, 睡覺 工資,教學行爲
* 程序員: 姓名, 性別, 年齡 ,吃飯, 睡覺 工資, 敲代碼
* 司機類別: 姓名, 性別, 年齡 ,吃飯, 睡覺 工資 開車
*
*
* 動物類別:  體重, 顏色, 吃
* 狗類別:   體重,顏色, 吃, 咬人
* 二哈類別: 體重,顏色, 吃, 咬人 逗主人開心,汪汪,你好帥
*
*
*
* 多態:一個對象有不同的行爲,或者是同一個行爲針對不同的對象,產生不同的結果,要想有多態,就要先有繼承,js中可以模擬多態,但是不會去使用,也不會模擬,(有了繼承,纔能有多態)
*

 

//例子:
    //人,都有姓名,性別,年齡, 吃飯, 睡覺, 玩
    //學生,都有姓名,性別,年齡, 成績, 吃飯, 睡覺, 玩 ,學習的行爲
    //js中通過原型來實現繼承(相同的代碼太多,造成了代碼的冗餘(重複的代碼))

function Person(name,age,sex) {
  	this.name=name;
  	this.sex=sex;
  	this.age=age;
  }
  Person.prototype.eat=function () {
  	console.log("人可以吃東西");
  };
  Person.prototype.sleep=function () {
  	console.log("人在睡覺");
  };
  Person.prototype.play=function () {
  	console.log("生活就是不一樣的玩法而已");
  };
  
  
  function Student(score) {
  	this.score=score;
  }
  //改變學生的原型的指向即可==========>學生和人已經發生關係
  Student.prototype=new Person("小明",10,"男");
  Student.prototype.study=function () {
  	console.log("學習很累很累的哦.");
  };
  
  var stu=new Student(100);
  console.log(stu.name);
  console.log(stu.age);
  console.log(stu.sex);
  stu.eat();
  stu.play();
  stu.sleep();
  console.log("下面的是學生對象中自己有的");
  console.log(stu.score);
  stu.study();

 

10繼承案例

動物有名字,有體重,有吃東西的行爲
小狗有名字,有體重,有毛色, 有吃東西的行爲,還有咬人的行爲
哈士奇名字,有體重,有毛色,性別, 有吃東西的行爲,還有咬人的行爲,逗主人開心的行爲

function Animal(name,weight) {
	this.name=name;
	this.weight=weight;
}
//動物的原型的方法
Animal.prototype.eat=function () {
	console.log("天天吃東西,就是吃");
};

//狗的構造函數
function Dog(color) {
	this.color=color;
}
Dog.prototype=new Animal("哮天犬","50kg");
Dog.prototype.bitePerson=function () {
	console.log("哼~汪汪~咬死你");
};

//哈士奇
function ErHa(sex) {
	this.sex=sex;
}
ErHa.prototype=new Dog("黑白色");
ErHa.prototype.playHost=function () {
	console.log("哈哈~咬壞衣服,咬壞桌子,拆家..嘎嘎...好玩,開心不,驚喜不,意外不");
};
var erHa=new ErHa("雄性");
console.log(erHa.name,erHa.weight,erHa.color);
erHa.eat();
erHa.bitePerson();
erHa.playHost();

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章