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)前屬性是否可枚舉。