js進(jìn)階篇:對象和原型

1.js中沒有太明確的類的概念,每個function函數(shù)都可以看做是一個類,類中可以通過prototype屬性來添加這個
類中的方法和字段。
2.一般情況把對象賦值或者添加到一個函數(shù)的prototype屬性中,函數(shù)的prototype
對對象的值做出更改,對象本身也是會發(fā)生變化的,可以使用一種臨時函數(shù)來打破這種關(guān)系鏈。
臨時函數(shù)new F();

代碼示例:
var obj = {x:0,y:1};
var F = function(){};
F.prototype = obj;
var f = new F();
console.log(f); 

//實(shí)例化之后 obj這個對象會掛在到f對象的原型中
f.x = "zs"; //這個時候其實(shí)是為f這個對象添加了一個自身屬性。所有并沒有對原型屬性進(jìn)行覆蓋更改.
console.log(obj); //{x:0,y:1}; 所以這里的obj對象不會有任何變化,也就是說這里只是繼承了它的原型屬性。
如果瀏覽器支持ES5可以通過 Object.create();這個方法來直接使用,和臨時構(gòu)造器的函數(shù)等價

代碼示例:
var f = Object.create({x:2,y:3}); 

3.一個函數(shù)使用prototype添加方法屬性,和不使用prototype的區(qū)別:

function person(){}
person.name = function(){console.log("name")};  //相當(dāng)于使用了靜態(tài)方法  
person.prototype.age = function(){};     //通過new

由于使用了靜態(tài)方法:調(diào)用的時候直接 person.name();即可 如果new了之后會出錯
age屬于對象的方式,需要new之后使用。
4.使用 hasOwnProperty 方法可以判斷屬性是否存在(用來檢測是否含有自身屬性)。
5.for...in 遍歷對象時,只會遍歷可枚舉屬性。
6.自身屬性和原型屬性

代碼示例:
function func()
{
    this.name = "";    //自身屬性
}
func.prototype.hello = "";   //原型屬性

所謂自身屬性通過構(gòu)造器定義的屬性,原型屬性會掛載到prototype上。
通過 關(guān)鍵字 new之后會將屬性掛載到這個func中,然后就可以通過for in關(guān)鍵字查找。

var f = new func();
for(var p in f)
{
   if(f.hasOwnProperty(b))  //判斷是自身屬性
      console.log(p);       //判斷之后這里只會打印name這個屬性
}

這里我們也是可以這樣理解的:f.prototype == f.proto; //true

對象查詢屬性的方式,會首先在自身屬性中去查找,如果查找不到的話會通過proto到對象的原型中去查找,如果
通過原型依然沒有找到,會去原型對象的原型中再去查找,一直到找到或者屬性為null的時候?yàn)橹?。這里也可以得出
一個結(jié)論:js的原型鏈的本質(zhì)在于proto這個神秘的鏈接

7.對象可以通過 delete 刪除指定對象的屬性,當(dāng)刪除一個不存在的屬性時也同樣會返回true,用來刪除變量和其他,可配置屬性是無效的

示例:var a = "liu ying";
     delete a; //返回一個  false,嚴(yán)格模式下這樣做的話會直接報錯

8.Object.create()的使用
該方法接收兩個參數(shù),第一個參數(shù)是一個對象,第二個為可選參數(shù)。通過對象的屬性進(jìn)一步描述。傳入一個對象后
返回值會繼承傳入對象的屬性,通過對該返回值做修改,傳入的遠(yuǎn)對象值不會隨著變化。

代碼示例://
var a = {name:"liu ying",age:23};  
var b = create.Object(a);
b.name = "hello";  //對返回值做修改
console.log(a);    //{name:"liu ying",age:23}   這個時候a對象的值的屬性依然不會變化。
所以從這個屬性可以看出,打破了原有的引用關(guān)系鏈。

9.內(nèi)置構(gòu)造函數(shù)的原型是只讀的,Object.prototype = "liu ying",比如這樣設(shè)置,不會報錯,但是賦值是沒有
生效的。
10.hasOwnProperty可以用來檢測當(dāng)前的屬性是否是對象的自身屬性,如果是繼承的屬性將會返回false
11.constructor屬性:所有的對象都會從他的原型上去繼承一個constructor屬性,函數(shù)其實(shí)也是屬于一種特殊的對象。

代碼示例:
var a = function(){};
var b = new a();
b.constructor == Object;   //這里是返回一個true;
但是有些js的內(nèi)置對象,不通過實(shí)例化的方法也可直接比較,也會返回true。
比如:
document.constructor == Document;
document.form3.constructor == Form;

12.proto屬性:該屬性是一個訪問器,(一個getter函數(shù)和一個setter函數(shù)),它公開訪問它的對象的內(nèi)部prototype屬性(對象或null)。
proto的使用是有爭議的,盡量不要使用
13.Object.defineproperty()屬性
該屬性具備三個參數(shù),第一個為目標(biāo)對象,第二個為目標(biāo)對象的key值,第三個參數(shù)為對象配置參數(shù).詳細(xì)說明一下第三個參數(shù)
第三個參數(shù)和設(shè)置一般對象一樣,可以設(shè)置是否可枚舉(enumerable),是否可配置(configrable),是否可寫(writable);
這里默認(rèn)都是false.
如果設(shè)置不可枚舉,for.. in 的話是無法遍歷出來內(nèi)置的不可枚舉屬性的。通過Object.defineproperty可以創(chuàng)建對象
屬性:

代碼示例
var o = {x:0,y:1};
Object.defineproperty(o,"z",{
    configrable:true,
    enumerable:true,
    writable:true,
    value:5
});
console.log(o);    //{x:0,y:1,z:5}

除了添加可配置的屬性,還有一個特別強(qiáng)大的功能,就是get和set方法,配置get和set方法以后可以檢測當(dāng)前屬性的變化
如果屬性值變化的話,會自動觸發(fā)set方法.

代碼示例:
var o = {x:0,y:1};
Object.defineproperty(o,"x",{
    configrable:true,
    enumerable:true,
    writable:true,
    get:function()
    {
        return this.x;
    },
    set:function(newVal)
    {
        this.x = newVal;
    }
});
//這里的get和set如果我手動修改了o.x的值的話,set方法就會自動觸發(fā),然后get方法返回值。
o.x = 2;   //這個時候set方法就會觸發(fā)

14.Object.freeze()屬性可以凍結(jié)一個對象,使該對象為只讀。如果一個對象的屬性也為對象,則凍結(jié)無效,如果
需要徹底的凍結(jié)的話就要使用遞歸來層層使用 freeze()屬性來設(shè)置。
15.Object.getOwnPropertyDescriptor();該方法帶兩個參數(shù):對象和key,通過key查找該對象的自身屬性,然后會返回
當(dāng)前對象的一些信息(value,是否枚舉,是否可寫)等等.
16.getOwnPropertyNames(),接收一個參數(shù),需要是一個對象類型,根據(jù)傳入的數(shù)據(jù)返回一個數(shù)組(當(dāng)前的對象的key值);和Object.keys相比
個人覺得還是有一點(diǎn)相似之處的,不同的是該屬性包括不可枚舉的屬性名也會一起返回。
17.Object.getPrototypeOf() 接收一個對象,能夠返回該對象的原型。

代碼示例:
var Vue = function(){};
Vue.prototype.hello = function(){};
var vue = new Vue();
//這里把vue這個對象傳入 
var v = Object.getPrototypeOf(vue);
console.log(v);  //{hello:function(){}}  

18.Object.is()屬性,接收兩個值,判斷兩個值是否完全相等,返回一個布爾值。
19.Object.isFrozen() 方法判斷一個對象是否被凍結(jié)(frozen)。 這里的凍結(jié)指的是所有的配置屬性都是凍結(jié)狀態(tài),才會返回true
20.obj.propertyIsEnumerable(prop);可以判斷該對象的當(dāng)前屬性是否可枚舉。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持,譯者再次奉上一點(diǎn)點(diǎn)福利:阿里云產(chǎn)品券,享受所有官網(wǎng)優(yōu)惠,并抽取幸運(yùn)大...
    HetfieldJoe閱讀 3,079評論 4 14
  • 博客內(nèi)容:什么是面向?qū)ο鬄槭裁匆嫦驅(qū)ο竺嫦驅(qū)ο缶幊痰奶匦院驮瓌t理解對象屬性創(chuàng)建對象繼承 什么是面向?qū)ο?面向?qū)ο?..
    _Dot912閱讀 1,536評論 3 12
  • 不能把你留在身邊,不是你的過錯,而是我的失敗。在你曾經(jīng)愛過我的那些短暫歲月里,我或許是世界上最幸福的人,只是那些日...
    所未2017閱讀 633評論 3 1
  • 剛剛放完暑假。 兒女隨嫂子昨天從老家趕到我們這里佛山順德。 誰知今天一大清早,兒女在房間各自轉(zhuǎn)來轉(zhuǎn)去唱著兒歌,還一...
    小A歐閱讀 278評論 0 0
  • 1 昨天和寧先生忙里偷閑,去杭州玩了一下。我們是下午下班后,坐高鐵去的。一個小時的火車,很快就到了。 入住酒店的時...
    陳熙心有聆熙閱讀 611評論 0 3

友情鏈接更多精彩內(nèi)容