1.如何準確判斷一個變量是數組類型
2.寫一個原型鏈繼承的例子
3.描述new一個對象的過程
知識點#####
- 構造函數
function Foo(name,age){
this.name=name
this.age=age
this.class='class-1'
//return this //默認有這一行
}
var f=new Foo('zhangsan',20)
//var f1=new Foo('lisi',22) //創建多個對象
- 構造函數-擴展
var a={} //其實是var a=new Object()的語法糖
var b=[] //其實是var b=new Array()的語法糖
function Foo(){...} //其實是var Foo=new Function(...)
//使用instanceof判斷一個函數是否是一個變量的構造函數
所有的引用類型(對象、數組、函數)都有構造函數,a的構造函數是Object(),b的構造函數是Array(),Foo的構造函數是Function()。所以假如想要判斷一個變量是否為數組就可以使用
var a={}
a instanceof Array //false
- 原型規則和實例
所有的引用類型都具有對象特性,即可自由擴展屬性(null除外)
所有引用類型都有一個
__proto__ //隱式原型
屬性,屬性值是一個普通的對象所有函數都有一個
prototype //顯示原型
屬性,屬性值也是一個普通的對象所有引用類型的
__proto__
屬性值指向它的構造函數的prototype
的屬性值-
當試圖得到一個引用類型的某個屬性時,如果這個對象本身沒有這個屬性,那么會去它的
__proto__
(即它構造函數的prototype)中尋找var obj={};obj.a=100; var arr=[];arr.a=100; function fn(){} fn.a=100 console.log(obj.__proto__) console.log(arr.__proto__) console.log(fn.__proto__) console.log(fn.prototype) console.log(obj.__proto__===Object.prototype) //true
//構造函數
function Foo(name,age){
this.name=name
}
Foo.prototype.alertName=function(){ //由于prototype是一個普通對象,所以也可以擴展屬性
alert(this.name)
}
//創建實例
var f=new Foo('zhangsan')
f.printName=function(){
console.log(this.name)
}
//測試
f.printName() //zhangsan
f.alertName() //f沒有alertName屬性,于是去f._proto_即Foo.prototype中查找
由對象調用原型中的方法,this指向對象
//循環對象自身的屬性
var item
for(item in f){
//高級瀏覽器已在for in中屏蔽了來自原型的屬性
//但是這里建議還是加上這個判斷以保證程序的健壯性
if(f.hasOwnProperty(item)){
console.log(item)
}
}
- 原型鏈
//在剛剛的代碼中加入
f.toString() //要去f.__proto__.__proto__中查找
所有的引用類型都有__proto__
屬性,且__proto__
屬性值指向它的構造函數的prototype
的屬性值,所以當f不存在toString時,便會在f.__proto__
即Foo.prototype
中查詢,而Foo.prototype
中也沒有找到toString。由于Foo.prototype
也是一個對象,所以它隱式原型__proto__
的屬性值便指向它的構造函數Object的prototype
的屬性值。
//試一試
console.log(Object.prototype)
console.log(Object.prototype.__proto__) //為了避免死循環,所以此處輸出null
原型鏈
- instanceof
用于判斷引用類型屬于哪個構造函數的方法
f instanceof Foo
的判斷邏輯是f
的__proto__
一層層向上能否對應到Foo.prototype
,再試著判斷f instanceof Object
解題#####
1.如何準確判斷一個變量是數組類型
使用instanceof
var arr=[]
arr instanceof Array //true
typeof arr //object typeof無法準確判斷是否是數組
2.寫一個原型鏈繼承的例子
//簡單示例,比較low,下面有更貼近實戰的例子
//動物
function Animal(){
this.eat=function(){
console.log('Animal eat')
}
}
//狗
function Dog(){
this.bark=function(){
console.log('Dog bark')
}
}
Dog.prototype=new Animal()
//哈士奇
var hashiqi=new Dog()
//封裝一個DOM查詢
function Elem(id){
this.elem=document.getElementById(id)
}
Elem.prototype.html=function(val){
var elem=this.elem
if(val){
elem.innerHTML=val
return this //鏈式操作
}else{
return elem.innerHTML
}
}
Elem.prototype.on=function(type,fn){
var elem=this.elem
elem.addEventListener(type,fn)
return this //鏈式操作
}
var div1=new Elem('div1')
// console.log(div1.html());
// div1.html('<p>Hello</p>');
// div1.on('click',function(){
// alert('clicked')
// });
div1.on('click',function(){alert('clicked')}).html('<p>鏈式操作</p>')
//在之前的函數中增加了return this,由div1調用時便會返回當前對象,即div1,便可以實現鏈式操作
3.描述new一個對象的過程
function Foo(name,age){
// this={}
this.name=name
this.age=age
this.class='class-1'
//return this
}
var f=new Foo('zhangsan',20)
//var f1=new Foo('lisi',22) //創建多個對象
創建一個新對象
this指向這個新對象 this={}
執行代碼,即對this賦值 this.xxx=xxx
返回this return this