JS高級特性(三)

五、原型(prototype)

1、研究函數對象的原型屬性

<!DOCTYPE html>
<html>
  <head>
    <title>01_研究函數對象的原型屬性.html</title>
	
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    This is my HTML page. <br>
  </body>
  <script type="text/javascript">
  	//原型是函數對象的一個屬性(普通對象是沒有原型屬性的.).
	function Hero(){
		this.name = "zhangwuji";
		this.sayMe = function(){
			alert("i am zhangwuji.");
		}
	}
	
	//調用函數對象Hero的屬性和方法:new Hero()
	var hero = new Hero();
	
	//調用函數對象Hero的屬性或方法時,實際上調用new之後的hero對象.
	//alert(hero.name);
	
	//調用函數對象的原型屬性,是應該調用Hero對象還是hero對象呢?
	//hero.prototype;
	Hero.prototype;
	
	
	
	
  </script>
</html>

2、利用原型增加函數對象的屬性或方法

<!DOCTYPE html>
<html>
  <head>
    <title>02_利用原型增加函數對象的屬性或方法.html</title>
	
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    This is m
<script type="text/javascript">
//	function Hero(){
//		this.name = "zhangwuji";
//		this.sayMe = function(){
//			alert("i am zhangwuji.");
//		}
//	}
	
	//普通對象
//	var hero = new Hero();
	
	//hero.value = "zhouzhiruo";
	
	//利用原型爲函數對象增加屬性或方法.
	//函數對象.prototype.新的屬性名 = 新的屬性值;
	//Hero.prototype.value = "zhouzhiruo";
	
	//alert(hero.prototype.value);		//output	zhouzhiruo
	//alert(hero.value);
	
//	Hero.prototype.sayVal = function(){
//		alert("i am zhouzhiruo.");
//	}
//	
//	alert(hero.sayVal());
	
	//利用原型增加的屬性和方法與上午說的增加屬性和方法的區別?利用原型增加屬性和方法更優
	//1 定義一個函數對象
	function Hero(){
		this.name = "zhangwuji";
		this.sayMe = function(){
			alert("i am zhangwuji.");
		}
	}
	
	//2 (分散形式)利用原型增加屬性和方法
//	Hero.prototype.value = "zhouzhiruo";
//	Hero.prototype.sayVal = function(){
//		alert("i am zhouzhiruo.");
//	}
	
	//學習JSON時
//	var method = {
//		add : function(a,b){
//			return a+b;
//		}
//	}
	
	/*
	 * (集中方式)將增加屬性和方法的內容,集中寫在一起
	 * 	* 格式:函數對象.prototype = 新的對象
	 * 	* 注意:只能先增加,再new對象
	 * (分散形式)
	 * 	* 先new對象和後new對象,沒有關係
	 */
	Hero.prototype = {
		value : "zhouzhiruo",
		sayVal : function(){
			alert("i am zhouzhiruo.");
		}
	}
	
	//3 new對象
	var hero = new Hero();
	
	//4 測試
	alert(hero.value);
	hero.sayVal();
	
</script>
</html>

3、函數對象的屬性或方法與原型的屬性和方法同名

<!DOCTYPE html>
<html>
  <head>
    <title>03_函數對象的屬性或方法與原型的屬性和方法同名.html</title>
	
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    This is my HTML page. <br>
  </body>
  <script type="text/javascript">
  	/*
  	 * 函數對象的屬性或方法與原型的屬性或方法同名時:
  	 * 	* 調用的屬性和方法,是函數對象的屬性和方法
  	 * 	* 函數對象本身的屬性和方法與原型的屬性和方法同時存在
  	 * 	* 函數對象本身的屬性和方法的優先級要高於原型上的屬性和方法
  	 */
	function Hero(){
		this.name = "zhangwuji";
		this.sayMe = function(){
			alert("i am zhangwuji.");
		}
	}
	
	//原型增加的屬性和方法,到底有沒有增加上去呢?
	Hero.prototype = {
		name : "zhouzhiruo",
		sayMe : function(){
			alert("i am zhouzhiruo.");
		}
	}
	
	var hero = new Hero();
	
	alert(hero.name);			//output	zhangwuji
	
	delete hero.name;
	
	alert(hero.name);			//output	zhouzhiruo
	
	
	
  </script>
</html>

4、利用原型重新定義函數對象

<!DOCTYPE html>
<html>
  <head>
    <title>04_利用原型重新定義函數對象.html</title>
	
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    This is my HTML page. <br>
  </body>
  <script type="text/javascript">
  	//定義一個空的函數對象
	function Hero(){}
	
	//函數對象的屬性和方法,都定義在原型上
	Hero.prototype = {
		name : "zhangwuji",
		sayMe : function(){
			alert("i am zhangwuji.");
		}
	}
	
  </script>
</html>

5、擴展內建對象的屬性或方法

<!DOCTYPE html>
<html>
  <head>
    <title>05_擴展內建對象的屬性和方法.html</title>
	
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    This is my HTML page. <br>
  </body>
  <script type="text/javascript">
//  //爲原型 Array對象增加一個判斷的函數
//	Array.prototype.inArray = function(color){
//		//this指代Array對象
//		for(var i = 0, len = this.length; i < len; i++){
//			//"==="叫全等號:值和類型;"!=="叫全不等號
//			if(this[i] === color){
//				return true;
//			}
//		}
//		return false;
//	}
//		
//	//定義一個Array對象
//	var a = ["red", "green", "blue"];
//		
//	//測試
//	alert(a.inArray("red"));		//true
//	alert(a.inArray("yellow"));		//false

	function inArray(arr,color){
		for(var i = 0, len = arr.length; i < len; i++){
			//"==="叫全等號:值和類型;"!=="叫全不等號
			if(arr[i] === color){
				return true;
			}
		}
		return false;
	}
	
	var a = ["red", "green", "blue"];
	
	alert(inArray(a,"red"));	//output	true
	
	/*
	 * 以上兩種寫法哪種更好?
	 * 	* (更好)一種通過原型擴展內建對象
	 * 	* 自定義函數完成需求
	 * 但是,一般不建議大家使用原型來擴展內建對象.
	 * 	* 擴展內建對象這種方式不好.(內建對象是底層提供的,最好不要修改)
	 * 但是,介紹js庫的時候,有prototype.
	 * 	* 對於javascript原型這個概念,討論的是比較激烈?
	 * 		* (A)正面,支持這種用法,代表性的是prototype庫.
	 * 		* (B)反面,不支持.
	 * 關於利用原型擴展內建對象,瞭解即可.
	 */
	
	
  </script>
</html>

六、繼承

1、利用原型實現繼承

<!DOCTYPE html>
<html>
  <head>
    <title>01_利用原型實現繼承.html</title>
	
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    This is my HTML page. <br>
  </body>
  <script type="text/javascript">
  	function A(){
		this.a = "a";
		this.sayA = function(){
			alert("this is a.");
		}
	}
	
	var a = new A();
	
	function B(){
		this.b = "b";
		this.sayB = function(){
			alert("this is b.");
		}
	}
	
	B.prototype = a;
	
	//測試:函數對象B就"繼承"了函數對象A
	var b = new B();
	
//	alert(b.b);
//	b.sayB();
//	
//	alert(b.a);
//	b.sayA();
	
//	b.a = "c";
//	b.sayA = function(){
//		alert("this is c.")
//	}
//	
//	alert(b.a);
//	b.sayA();
	
//	b.c = "c";
//	b.sayC = function(){
//		alert("this is c.")
//	}
//	
//	alert(b.c);
//	b.sayC();
	
  </script>
</html>

2、只繼承於原型

<!DOCTYPE html>
<html>
  <head>
    <title>02_只繼承於原型.html</title>
	
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    This is my HTML page. <br>
  </body>
  <script type="text/javascript">
//  function A(){
//		this.a = "a";
//		this.sayA = function(){
//			alert("this is a.");
//		}
//	}
//	
//	function B(){
//		this.b = "b";
//		this.sayB = function(){
//			alert("this is b.");
//		}
//	}
//	
//	B.prototype = A.prototype;
//	
//	//測試
//	var b = new B();
//	
//	alert(b.a);
//	b.sayA();
	
	/******************************************/
	
//	function A(){}
//	
//	A.prototype = {
//		a : "a",
//		sayA : function(){
//			alert("this is a.")
//		}
//	}
//	
//	function B(){}
//	
//	B.prototype = {
//		b : "b",
//		sayB : function(){
//			alert("this is b.")
//		}
//	}
//	
//	B.prototype = A.prototype;
//	
//	var b = new B();
//	
////	alert(b.a);
////	b.sayA();
//	
//	alert(b.b);
//	b.sayB();
	
	/***************************************/
	
	function A(){}
	
	A.prototype = {
		a : "a",
		sayA : function(){
			alert("this is a.")
		}
	}
	
	function B(){
		this.b = "b";
		this.sayB = function(){
			alert("this is b.");
		}
	}
	
	B.prototype = A.prototype;
	
	var b = new B();
	
	alert(b.b);
	b.sayB();
	
	alert(b.a);
	b.sayA();
	
  </script>
</html>

3、解決多函數之間的繼承關係

<!DOCTYPE html>
<html>
  <head>
    <title>03_解決多函數對象之間的繼承關係.html</title>
	
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    This is my HTML page. <br>
  </body>
  <script type="text/javascript">
  	function A(){}
	
	A.prototype = {
		a : "a",
		sayA : function(){
			alert("this is a.")
		}
	}
	
	function B(){}
	
	//這種方式利用原型爲函數對象B增加屬性和方法(集中方式)
//	B.prototype = {
//		b : "b",
//		sayB : function(){
//			alert("this is b.")
//		}
//	}
	
	//分散形式
//	B.prototype.b = "b";
//	B.prototype.sayB = function(){
//		alert("this is b.")
//	}
	
	/*
	 * 分析得出這句話出問題了
	 * 	* 因爲B.prototype多次調用
	 * 		* 出現的順序有關係?誰先定義,誰被覆蓋
	 * 		* 原型定義屬性和方法的形式有關係?沒有關係
	 */
	B.prototype = A.prototype;
	
//	B.prototype = {
//		b : "b",
//		sayB : function(){
//			alert("this is b.")
//		}
//	}
	
	/*
	 * 條件:
	 * 	* 先實現函數對象B"繼承"函數對象A的內容
	 * 	* 再利用原型爲函數對象B增加屬性和方法(分散形式)
	 */
	B.prototype.b = "b";
	B.prototype.sayB = function(){
		alert("this is b.")
	}
	
	var b = new B();
	
	alert(b.a);
	b.sayA();
	
	alert(b.b);
	b.sayB();
	
	
	
	
  </script>
</html>

4、普通對象之間的繼承

<!DOCTYPE html>
<html>
  <head>
    <title>04_普通對象之間的繼承.html</title>
	
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    This is my HTML page. <br>
  </body>
  <script type="text/javascript">
  	//對象之間的繼承
	
	//該函數接受一個對象並返回它的副本
	function extendCopy(p){
		var z = {};	//定義一個空的對象z
		for(var i in p){	//var i =0 ; i < p.length ; i++
			z[i] = p[i];	//都當做數組處理的話,可以理解
		}
		//uber屬性:將p作爲z的父級,將z指向p的原型
		z.uber = p;
		return z;
	}
	//定義普通對象a,但是對象a不是函數對象	
	var a = {
		name : "a"
	}
	//暫且將b也當作普通對象來看待
	var b = extendCopy(a);
	b.toStr = function(){return this.name;};
		
	alert(b.toStr());		//output	a

  </script>
</html>




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