標籤:
hasOwnProperty:是用來判斷一個對象是否有你給出名稱的屬性或對象,此方法無法檢查該對象的原型鏈中是否具有該屬性,該屬性必須是對象本身的一個成員。
isPrototypeOf是用來判斷要檢查其原型鏈的對象是否存在於指定對象執行個體中,是則返回true,否則返回false。
instanceof 操作檢查對象中是否有名為 property 的屬性。也可以檢查對象的原型,判斷該屬性是否為原型鏈的一部分.
Java代碼
hasOwnProperty:
var obj = {a:1,b:2}
obj.hasOwnProperty(‘a‘)
isPrototypeOf:
function F(){}
var fn = new F()
F.prototype.isPrototypeOf(fn)
前者是判斷對象中是否存在某個屬性,後者是判斷對象是否是原型鏈的對象。
JavaScript中isPrototypeOf函數方法是返回一個布爾值,指出對象是否存在於另一個對象的原型鏈中。使用方法:
object1.isPrototypeOf(object2)
其中object1為必選項,一個對象的執行個體。
object2為必選項,另一個對象,將要檢查其原型鏈。
如果 object2 的 原型鏈中包含object1,那麼JavaScript中isPrototypeOf函數方法返回 true。
原型鏈可以用來在同一個物件類型的不同執行個體之間共用功能。
如果 object2 不是一個對象或者 object1 沒有出現在 object2 中的原型鏈中,
JavaScript中isPrototypeOf函數方法將返回 false。
以下樣本闡述了JavaScript中isPrototypeOf函數方法的用法。
function test(){
var re = new RegExp(); //初始設定變數。
return (RegExp.prototype.isPrototypeOf(re)); //返回 true。
}
constructor:物件建構器。
prototype:訪問物件建構器的原型,只有函數才具有這個屬性。
isPrototypeOf:如果對象 A 存在於 對象obj的原形鏈中,則 A.isPrototypeOf(obj)返回true,而obj必定繼承了A 的屬性。
__proto__:訪問對象的原型鏈在當前對形象位置的上一級對象,即對象的父級對象,非W3C 或 ECMAscript 標準,是瀏覽器對原型繼承的一種實現手段,存在於firefox 和 chrome ,IE下不存在這個屬性。
在對象的繼承關係中,對象obj的構造器 constructor 其實是存在於原型鏈中的,
即 obj.constructor 實際上是 obj.__proto__.constructor, obj.hasOwnProperty(‘constructor‘); 為 false
function Y() {this.y=99;}
var obj = new Y();
console.log(obj.constructor); //Y
console.log(obj.hasOwnProperty(‘constructor‘)); //false
console.log(obj.__proto__.hasOwnProperty(‘constructor‘)); //true
//=====
function X(){this.x=88; }
function Y() {this.y=99;}
Y.prototype = new X();
var obj = new Y();
console.log(obj.constructor); //X
console.log(obj.hasOwnProperty(‘constructor‘));//false
console.log(obj.__proto__.hasOwnProperty(‘constructor‘)); //false
console.log(obj.__proto__.__proto__.hasOwnProperty(‘constructor‘)); //true
訪問對象時,對於 obj.__proto__.x=value 則必定有 obj.x=value,
obj.constructor.prototype 上的屬性將被儲存在obj.__proto__中。
function Y() {this.y=99;}
Y.prototype = {a:11};
var obj = new Y();
Y.prototype.a=77;
console.log([obj.a,obj.__proto__.a,obj.y,obj.__proto__.y]);
/*77,77,99,obj.__proto__.y 是 undefined,y 屬性是由物件建構器直接產生的而不是從原形鏈繼承來的*/
new 運算構造obj對象之後,obj訪問繼承來的屬性時,是通過__proto__ 訪問的,而不是通過obj.constructor.prototype 訪問,
因此,如果修改obj.constructor.prototype指向另一個對象,並不會影響obj繼承原有的屬性。
Y.prototype = {b:22};
console.log(obj.b); //undefined
console.log(obj.a); //77
in:如果對象 obj 有屬性 property(包括繼承來的和不可列舉屬性,不同於 for in 迴圈中的 in,for in 忽略了不可列舉屬性), 則‘property‘ in obj 返回 true,這個運算不存在於初期版本的javascript。
propertyIsEnumerable:如果對象obj上的屬性property可以被列舉出來(可被 for in 迴圈遍曆),則 obj.propertyIsEnumerable(‘property‘) 返回true,值得注意的是,propertyIsEnumerable對繼承來的屬性一律判斷為false,這一般被認為是ECMA Script 規範的一個設計上的錯誤。
hasOwnProperty:如果對象obj 上的屬性 property 不是繼承的來的,則 obj.hasOwnProperty(‘property‘) 返回true。
delete:刪除對象自身上的屬性,不能刪除繼承來的屬性,在 舊的瀏覽器中,不能通過 delete window.x 來刪除使用 var 聲明的全域變數 x,但是在最新的瀏覽器已經可以了,包括 IE 9.
var f = function(){};
f.prototype = { x:99 };
var o = new f;
console.log(o.hasOwnProperty(‘x‘)); //false
console.log(o.x); //99
delete o.x ;
console.log(o.x); //99
var x = 1;
window.hasOwnProperty(‘x‘); //true
delete window.x;
console.log(x); // error,x is not defined
instanceof:如果obj對象是建構函式Fun的一個執行個體,則 obj instanceof Fun 返回 true,值得注意的是,instanceof 並不檢查 Fun 函數,而是檢查 Fun.prototype,是基於"原形鏈"的,因此,即使 obj instanceof Fun 返回 true,obj 也可能不具有 Fun 構造器中定義的屬性,因為 Fun 不一定是 obj 的構造器。
function Bar(){}
function A(){}
Bar.prototype = new A();
var bar = new Bar();
console.log(bar instanceof Bar); //true
Bar.prototype = new A();
console.log(bar instanceof Bar); //false
/*instanceof 檢測 函數的 prototype, 後一個 new A 不等於前一個 new A,(不相同的對象不會相等)*/
關於instanceof,試考察下面代碼:
function P(){this.p=11;};
var pro = new P();
function X() {this.x=88;}
function Y() {this.y=99;}
Y.prototype =pro;
var obj = new Y();
1、物件建構器在哪
console.log(obj.hasOwnProperty(‘constructor‘)); //false
console.log(obj.constructor); //P
console.log(obj.__proto__.constructor);//P
console.log(obj.__proto__.constructor === Y.prototype.constructor); //true
這說明執行new時,obj.constructor 即 obj.__proto__.constructor 實際是 Y.prototype.constructor 而不是 Y.
2、物件建構器修複
但是,有一點小問題,考察一下 y 屬性:
console.log(obj.y); // 99
console.log(obj.__proto__.y); //undefined
y 屬性既然不是來自於“原型鏈”,那自然是來自於物件建構器,但是 P 函數中並沒有定義 y 屬性,
從“類式繼承” 形成的“繼承鏈” 看來,P 只是“繼承鏈”的源頭,也就是最頂級的 “基類”, obj 對象執行個體的的構造來源於“子類” y 函數,
這是 js 對象繼承系統中 “類比類式繼承” new 與“原型繼承” prototype 之間的一點裂縫,
很多人執著於修複這個裂縫,於是有了構造器修複的做法.
預設狀態下聲明一個函數fun,有fun.prototype.constructor===fun,於是:
obj.constructor = Y ; //修複構造器,賦一個constructor屬性來覆蓋掉繼承鏈上的constructor
console.log(obj.hasOwnProperty(‘constructor‘)); //true
console.log(obj.constructor); //Y
console.log(obj.__proto__.constructor); //P
3、obj instancof Fun 為 true 並不意味著 Fun 一定是 obj 對象的構造器,Fun 可能並不存在於 obj 的繼承鏈中:
X.prototype = pro;
console.log(obj instanceof X); //true
console.log(obj.x);//undefined , X 不是 obj 的構造器
console.log(obj instanceof Y); //true
console.log(obj.y);//99
上面的代碼中P函數如果改為
function K(){ this.k=66; }
function P(){this.p=11;};
P.prototype = new K();
那麼未修複構造器前,繼承鏈上的建構函式將是K而不是P,也會有:
console.log(obj instanceof X); //true
console.log(obj.x);//undefined
console.log(obj instanceof Y); //true
console.log(obj.y);//99
console.log(obj instanceof K); //true
console.log(obj.k); //66
4、Object.create()
新版本的 ECMAScript 為 Object 對象擴充了一些方法,
Object.create(pro)可以基於 pro 為原型建立一個對象,其效果相當於
var f = function(){};
f.prototype = pro;
var obj = new f();
try:
function P(){this.p=11;}
function K(){this.k=22;}
function F(){this.f=33;}
var pro = new K();
P.prototype = pro;
var o= new P();
var obj = Object.create(o);
console.log(o,obj); // 都是 {p:11,k:22}
console.log(obj.constructor); // K
console.log(obj.__proto__.constructor); //k
console.log(obj instanceof P); //true
console.log(obj instanceof K); //true
console.log(obj instanceof F); //false
F.prototype = pro;
console.log(obj instanceof F); //true
5、Object 與 Function:
console.log(Function instanceof Object); //true
console.log(Object instanceof Function); //true
先有 Function 還是先有 Object ?下面這個現象或許能解釋,Object 才是“最頂級”的對象
console.log(Object.__proto__.__proto__===Function.prototype) ; // false
console.log(Function.__proto__.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null ,Object 的對象原型已經是女媧級的了
javascript 中isPrototypeOf 、hasOwnProperty、constructor、prototype等用法