- 如何判斷一個變量是數(shù)組類型
- 寫一個原型鏈繼承的例子
- 描述new一個對象的過程
- zepto(或其他框架)源碼中如何使用原型鏈
構造函數(shù)
function Foo(name,age){
this.name = name
this.age = age
this.class = 'class-1'
//return this //默認有這一行
}
var f = new Foo('greentea',20)
//var f1 = new Foo('lisi',22) //創(chuàng)建多個對象
在函數(shù)中,一般函數(shù)名大寫開頭的都是構造函數(shù).這是一種規(guī)范.
那么f是如何變成一個對象的呢?
首先,在new之前,這個構造函數(shù)中的this是一個空對象,在構造函數(shù)穿參(或者不傳),依次將參數(shù)賦值給this的屬性,然后將這個this作為返回值,即使return this這一句沒有,它也默認返回this.依次,這個f就這樣new出來的.
var a = {} 其實是var a = new Object()的語法糖
var a = [] 其實是var a = new Array()的語法糖
function Foo(){...}其實是var Foo = new Function(...)
使用instanceof判斷一個函數(shù)是否是一個變量的構造函數(shù)
原型
1.所有的引用類型(數(shù)組,對象,函數(shù)),都具有對象特性,即可自由擴展屬性(除了'null'以外)
2.所有的引用類型(數(shù)組,對象,函數(shù)),都有一個__proto__
屬性,屬性值是一個普通的對象
3.所有的函數(shù),都有一個prototype屬性,屬性值也是一個普通的對象
4.所有的引用類型(數(shù)組,對象,函數(shù)),__proto__
屬性值指向它的構造函數(shù)的'prototype'屬性值
5.當試圖得到一個對象的某個屬性時,如果這個對象本身沒有這個屬性,那么會去它的__proto__
(即它的構造函數(shù)的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);
//構造函數(shù)
function Foo(name,age){
this.name = name
}
Foo.prototype.alertName = function(){
alert(this.name)
}
//創(chuàng)建示例
var f = new Foo('greentea');
f.printName = function(){
console.log(this.name)
}
//測試
f.printName()
f.alertName()
其中,
this
指代的就是f
,你從原型中繼承來的方法中里的this,它也指向f
循環(huán)對象自身的屬性
var item
for(item in f){
//高級瀏覽器已經(jīng)在for in中屏蔽了來自原型的屬性
//但是這里建議大家還是加上這個判斷,保證程序的健壯性
if(f.hasOwnProperty(item)){
console.log(item)
}
}
原型鏈
下面,接著看這個例子...
//構造函數(shù)
function Foo(name,age){
this.name = name
}
Foo.prototype.alertName = function(){
alert(this.name)
}
//創(chuàng)建示例
var f = new Foo('greentea');
f.printName = function(){
console.log(this.name)
}
//測試
f.printName()
f.alertName()
f.toString() //要去f.__proto__.__proto__中查找
instanseof
用于判斷引用類型屬于哪個構造函數(shù)的方法
f instanceof Foo 的判斷邏輯是:
f的proto一層一層往上,能否對應到Foo.prototype
下面是一些例子
//動物
function Animal(){
this.eat = function(){
console.log('animal eat');
}
}
//狗
function Dog(){
this.bark = function(){
console.log('dog bark');
}
}
Dog.prototype = new Animal();
//薩摩
var samo = new Dog();
在這段代碼中,new 了Animal構造函數(shù)的對象給了Dog.prototype,Dog.prototype的原型本來就是個對象,只是現(xiàn)在它又擁有了Animal的屬性.
//封裝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)
}
var div1 = new Elem('div1')
div1.html('<p>hello imooc</p>')
div1.on('click',function(){
alert('clicked')
})