javascript 中isPrototypeOf 、hasOwnProperty、constructor、prototype等用法

來源:互聯網
上載者:User

標籤:

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等用法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.