五、原型(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>