//第一種方式:字面量 var o1 = {name:"o1"};//{name: "o1"} var o2 = new Object({name:"o2"});//{name: "o2"} //第二種方式:構造函數 var M = function(name){this.name = name;}; var o3 = new M("o3");//M {name: "o3"} //第三種方式:Object.create(o4.__proto__===p//true) var p = {name:"p"}; var o4 = Object.create(p);//{}
原理:ECMAScript中描述了原型鏈的概念,並將原型鏈做爲實現繼承的主要方法。其基本思想是利用原型讓一個引用類型繼承另外一個引用類型的屬性和方法。在JavaScript中,用__proto__
屬性來表示一個對象的原型鏈。html
任何一個函數,被new使用了,new後面的函數就是一個構造函數。構造函數能夠經過new
運算符來生成一個實例。數組
在聲明一個(構造)函數的時候,js引擎會自動給它加上一個prototype
屬性,此屬性會初始化一個空對象,即向原型對象。M.prototype.constructor===M;
返回true瀏覽器
原型對象怎麼能區分是被哪個構造函數引用的呢?原型對象中有一個構造器(constructor
),默認的是聲明的構造函數。o3.__proto__===M.prototype;
返回true函數
小提示:1.實例對象只有
__proto__
,沒有prototype
屬性。
2.構造函數有prototype
屬性。(也有__proto__
,由於函數也是一個對象。M.__proto__===Function.prototype;
返回true。)測試
instanceof的原理:用來判斷實例對象的__proto__
屬性和構造函數的prototype
屬性是否是同一個引用。/ 判斷類(構造函數)的prototype
對象是否存在於實例對象的原型鏈上。是則返回true。this
o3 instanceof M;
返回true(o3.__proto__===M.prototype;
返回true)o3 instanceof Object;
返回true(M.prototype.__proto__===Object.prototype;
返回true)M instanceof Function;
返回true。M instanceof Object;
返回true。*使用 instanceof 判斷 引用類型 屬於哪一個 構造函數 的方法。spa
*判斷一個對象是否爲數組:arr instanceof Array
prototype
*判斷一個對象的構造函數用constructor比較合理code
o3.__proto__.constructor===M;
//trueo3.__proto__.constructor===Object;
//falsefoo.prototype
)new
出來的結果爲第一步建立的對象;若是構造函數返回了一個「對象」,那麼這個對象會取代整個new
出來的結果。//模擬new運算符 var new2 = function(func){ var o =Object.create(func.prototype); //第一步 var k =func.call(o);//第二步 //第三步 if(typeof k ==="object"){ return k; }else{ return o; } } //驗證 o6=new2(M)//建立一個新對象 o6 instanceof M//rue o6 instanceof Object//true o6.__proto__.constructor===M//true
obj.__proto__ === Object.prototype
//構造函數 function Foo(name,age){ this.name = name; } Foo.prototype.alertName = function(){ alert(this.name);//this是f } //建立實例 var f = new Foo('zhangsan'); f.printName = function(){ console.log(this.name);//this是f } //測試 f.printName(); f.alertName();
var item; for(item in f){ // 高級瀏覽器已經在 for in 中屏蔽了來自原型的屬性 // 可是這裏建議仍是加上這個判斷,保證程序的健壯性 if(f.hasOwnProperty(item)){ console.log(item); } }
畫出一下代碼的原型鏈,便於理解。htm
//構造函數 function Foo(name,age){ this.name = name; this.age = age; //return this; // 默認有這一行 } var f = new Foo('zhangsan',21);
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('test'); div1.html('<p>hello world </P>').on('click',function(){console.log('clicked');})