---------------------- 題目-------------------------
1. 如何準確判斷一個變量是數組類型
//變量 instanceof Array
var arr = [];
arr instanceof Array;//true
typeof arr; //object,typeof是無法判斷是否是數組的
2. 寫一個原型鏈繼承的例子
function Person(name,sex){
this.name = name;
this.sex = sex;
}
Person.prototype.showName=function(){
alert(this.name);
};
Person.prototype.showSex = function(){
alert(this.sex);
};
function Worker(name,sex,job){
Person.call(this,name);
this.job = job;
}
for(var i in Person.prototype){
Worker.prototype[i]=Person.prototype[i];
}
Worker.prototype.showJob=function(){
alert(this.job);
};
var P1= new Person('blue','men');
var W1= new Worker('leo','men','coder');
P1.showName();
P1.showSex();
W1.showName();
W1.showSex();
W1.showJob();
*貼近實際開發原型鏈繼承的例子
/*------------封裝DOM查詢------------------*/
//(獲取一個dom節點,獲取內容,改變內容,綁定事件)
function Element(id){
this.elem = document.getElementById(id);
}
Element.prototype.html=function(val){
var elem = this.elem;
if(val){
elem.innerHTML = val;
//把整個對象(div1)返回出去
return this;//鏈式操作
}else{
//把當前html結構返回出來
return elem.innerHTML;
}
};
Element.prototype.on=function(type,fn){
var elem = this.elem;
elem.addEventListener(type,fn);
//把整個對象(div1)返回出去
return this;//鏈式操作
};
var div1 = new Element('main-outer');
div1.html('<p>test immoc</p>').on('click',function(){
alert('click');
}).html('<p>javascript</p>');
3. 描述new一個對象的過程(構造函數)
1. 創建一個新對象
2.this指向這個新對象
3. 執行代碼,即對this賦值
4. 返回this
function Foo(name,age){
this.name = name;
this.age = age;
this.class = 'class-1';
//構造函數默認不要寫return this,讓它自己返回就
// return this //默認有一行
}
// new 就是構造函數形成一個實例的過程
var f = new Foo('zhangsan',20);
//var f1 = new Foo('lisi',22);//創建多個對象
// 考察構造函數 new 原理
4. zepto(或其他框架)源碼中如何使用原型鏈
* 閱讀源碼是高效提高技能的方式
* 不能埋頭苦鉆有技巧在其中
* 慕課網搜“zepto設計和源碼分析”
--------------------------- 知識點-------------------------------
1. 構造函數
// 大寫字母開頭的函數是構造函數
// 構造函數類似于模板可以創建多個對象
function Foo(name,age){
this.name = name;
this.age = age;
this.class = 'class-1';
// return this //默認有一行
}
// new 就是構造函數形成一個實例的過程
var f = new Foo('zhangsan',20);
//var f1 = new Foo('lisi',22);//創建多個對象
//*new一個構造函數返回一個對象的過程
1、先new的時候把參數傳進去(當然也可以不傳)
2、new這個函數執行的時候,函數里邊的this會先變成一個空對象,
再this.name這些屬性的賦值,賦值完之后默認把this return回來,
賦值給f,f就具備了f.name='zhangsan'。
2. 構造函數--擴展
// 所有的引用類型(對象、數組、函數)都有構造函數;
//對象有構造函數、數組有構造函數、函數也有構造函數
var a ={}其實是var a = new Object()的簡寫;
a 的構造函數是 Object;
var a = []其實是var a = new Array()的簡寫;
a 的構造函數是Array
function Foo(){...}其實是var Foo = new Function(...);
Foo 的構造函數是Function;
//推薦寫法都推薦前面的寫法:
var a ={}; var a =[]; function Foo(){...}
* 使用instanceof判斷一個函數是否是一個變量的構造函數;
//判斷一個變量是否為“數組”:變量 instanceOf Array
3. 原型規則和示例
* 5條原型規則
// 原型規則是學習原型鏈的基礎
1.所有的引用類型(數組、對象、函數),都具有對象特性,即可自由擴展
屬性(除了"null"以外)
var obj = {}; obj.a =100;
var arr = []; arr.a =100;
function fn(){} fn.a =100;
2.所有的引用類型(數組、對象、函數不包括null),都有一個_proto_(隱式原型)
屬性,屬性值是一個普通的對象
console.log(obj._proto_);
console.log(arr._proto_);
console.log(fn._proto_);
3、所有的函數,都有一個prototype(顯式原型)屬性,屬性值也是一個普通的對象
console.log(fn.prototype);
4、所有的引用類型(數組、對象、函數),_proto_屬性值指向(完全等)它的構造函數
的 "prototype"屬性值
// var obj = new Object();
console.log(obj._proto_ === object.prototype);//true
5、當試圖得到一個對象的某個屬性時,如果這個對象(引用類型--數組、函數、對象)
本身沒有這個屬性,那么會去它的_proto_(即它的構造函數的prototype)中尋找。
//隱式原型等于它的構造函數顯式原型
//*****一個變量本身沒有屬性,它會去它的構造函數的顯式原型中去尋找********/
console.log(obj._proto_ === Object.prototype);
//構造函數
function Foo(name,age){
this.name = name;
}
Foo.prototype.showName=function(){
alert(this.name);
};
//創建示例
var f = new Foo('zhangsan');
f.consoleName = function(){
console.log(this.name);
};
//測試
f.consoleName();//'zhangsan'
//一個變量本身沒有屬性,它會去它的構造函數的顯式原型中去尋找
//無論是函數自身的屬性還是原型中得到的一個屬性,函數執行中的this永遠指向f自身;
f.showName(); //'zhangsan'
*循環對象的自身屬性*
/**高級瀏覽器已經在 for in中屏蔽了來自原型的屬性,但是這里建議大家還是加上這個判斷,保證程序的健壯性 **/
/**在遍歷f的時候判斷一下遍歷出來的item是不是能通過hasOwnProperty驗證;如果通過之后就說明是f自身的屬性,沒通過就說明是f通過原型得到的屬性**/
//for in 可以對一個對象進行循環的
var item;
for(item in f){
if(f.hasOwnProperty(item)){
console.log(item);
}
}
4.原型鏈
原型鏈示意圖.png
原型鏈示例.png
//構造函數
function Foo(name,age){
this.name = name;
}
Foo.prototype.showName=function(){
alert(this.name);
};
//創建示例
var f = new Foo('zhangsan');
f.consoleName=function(){
console.log(this.name);
};
//測試
f.cosoleName();
/**獲取的f隱式原型(f的構造函數顯式原型里面的定義的一個值就是定義
的showName這個屬性值并且執行了)里面的屬性**/
f.showName();
/**當這個對象沒有這個屬性的時候就會去它自身的一個隱式原型(它構造函
數的顯式原型)中去找***/
//構造函數是Foo 顯式原型是Foo.prototype.中并沒有toString這個東西
/*f.prototype構造函數的顯式原型也是一個對象,在它中尋找t oString這個
方法;要去它的隱式原型(f._proto_._proto_)中去找*/
/**原型鏈(去f的隱式原型(f._proto_)中去找,f._proto_沒有toString
f._proto_也是一個對象),在這個對象里面找toString,還得到它本身的隱式
原型中去找*/
f.toString();
5. instanceof--(類型判斷)---是原型鏈一個具體的表現而已)
//用于判斷引用類型屬于哪個構造函數的方法
f instaceof Foo的判斷邏輯是:
//》f的_proto_一層一層往上,能否對應到Foo.prototyoe
//》在試著判斷f instanceof Object