霸道總裁之js對象

對象

在大多數人的眼裏,js是一門面向對象(Object-Oriented)的語言,可是它與其餘的語言好比c++,java 這些面嚮對象語言 略有不一樣。
!!!艹,說人話
那問幾個問題吧:java

1.你知道js中對象的定義是什麼嗎?c++

答: 不就是一個散列表嘛~ 至關於key/value對.es6

var obj = {
    name:"jimmy",
    gender:"male"
}

2.那js裏面一切都是對象你能理解嗎?具體一點,你說一下,函數爲何是對象吧。
答:...。 (Ps:md!!! 函數哪裏是對象了。。。)面試

以上對話實際上是一道面試題。 是否是感受本身濛濛噠了~
壯士磨嘰, 其實js裏面一切都是對象是徹底有理有據的。但願可以好好理解,由於這個之後可能會區別你是磚家,仍是專家的一個重要分水嶺.
來咱們先說一說對象.函數

what's the Object?

這個問題就涉及了對象的定義。 上面說的沒錯,對象其實就是一個散列表而已。可是更深層次的說,你怎麼得到一個對象。
show me u code:指針

var obj = new Object();

上面一個例子很好的體現出,對象如何定義。
對象實際上是由 new + 構造函數 建立的。 關於這點就會涉及到模式的概念,你們有興趣能夠參考我前面一篇文章——"模式之辯". 並且還有一個限制, 你所建立的類型必須是引用類型。
聽不懂了吧~
總結下上面的,其實
對象 = new + 構造函數 || 字面量的引用類型
來上個栗子.code

var obj = new Function();  //對象
var obj = new Object();  //對象
var obj = {};  //對象
var str = "not a Object";  //不是對象

因爲string不是引用類型,因此它建立的實例不是對象~ 並且其餘的都是引用類型,因此結果都是對象.
可是對象還有幾個features, which are unique with other types.對象

1.對象的可增添性ip

什麼意思嘞?內存

var obj = {};
obj.name = "jimmy";
console.log(obj.name); //jimmy
var str = "a";
str.name = "jimmy";
console.log(str.name); //undefined

這個能夠充分的說明,對象類型和值類型的區別的。

2.等價判斷

怎麼判斷兩個對象是一個東西嘞?
用"==="唄。 來試一試.

var obj1 = new Object();
var obj2 = new Object();
console.log(obj1===obj2);  //false

艹,怎麼會這樣,兩個不都是對象嗎?並且我又沒動它。應該同樣啊~~~
騷年,不要把你判斷值類型的方法套在咱們偉大的對象上。
說明一下。若是判斷對象類型和值類型。
對象類型的判斷:
對象的等價是創建在大家的源是否相同(官方的說法叫地址).

var obj1= new Object();
var obj2 = new Object();

須要搞清楚,使用 new + 構造器 你是在新建實例,即你建立的是不一樣源的對象。
那如何同源嘞?

var obj1 = new Object({
name:"jimmy"
});
var obj2 = obj1;  //同源
var obj3 = new Object();
obj2.name = "sam";
console.log(obj1.name);  //sam
console.log(obj1===obj2);  //true
console.log(obj2===obj3);  //false

其實到這裏,咱們須要將咱們之前的所說的對象再抽象一層。 你說使用的var obj1 裏面的obj1 並非對象,而只是一個指針, 指向着這個對象。 那這個對象在哪裏嘞? 在你的內存當中。 艹~~~ 好難理解。
爲了你們更好的理解一切都是對象,我這裏會以大衆的視角來說解的。(固然若是你已經理解了,能夠忽略下面非正式的說法~)
回退~
咱們仍是將obj1和obj2說成是對象。 上面能夠看出,只有是同源的對象纔會相等。
值類型的判斷:
這個就很好說了, 你知道1===1嗎? 恩,知道~~~
恭喜你,你已經知道值類型的判斷了。

var num1 = 2;
var num2 = 2;
console.log(num1===num2);  //true

說了這麼多,那值類型和引用類型到底有哪些呢?
值類型: string,number,Boolean,null,undefined,Symbol(es6纔出的)
引用類型: Object,Array,RegExp,Function,Date
恩,大體就這麼多。
~腳嘚瑪嘚(Ps:日語)
大哥,不對呀~ 爲何有時候我使用string類型的時候又能夠在後面使用方法嘞?您看:

var s = "jimmy";
console.log(s.length);  //5

不是說值類型不是對象嗎? 那它怎麼會有對象的feature呢?
對,這個問題問的好~
來,再給你們科普一個類型,基本包裝類型。

基本包裝類型

我相信寫過2k+代碼的童鞋應該會遇到這樣的狀況。好比我要知道這個字符串是否是空,可使用這樣的判斷:

var s = "jimmy";
if(s.length===0){
    console.log("這是一個空的string");
}

咦~ 爲何值類型的又可使用屬性嘞?
事實上, ECMAScript 規定的類型詳細的分有2.5種.
除了上面說的兩種還有一種基本包裝類型.
基本包裝類型: String,Number,Boolean.
其實值類型 包括基本包裝類型的。
那他的特性是什麼嘞?
再看一下上面的例子:

var str= "jimmy";
console.log(str.length);  //5
str.length = 6;
console.log(str.length);  //5

咱們用事實說話, 上面的結果很好的證實了,基本包裝類型的特性。 即 若是你想讀取值類型的相關屬性和方法,
js引擎會默認幫你將值類型,臨時變爲一個對象使用。可是這層保存存在的時間,只是你代碼執行的那一瞬間。
再次證實:

var str = "jimmy";
str.male = "male";  //執行成功,但當即被銷燬
console.log(str.male);  //undefined

上面例子的執行過程是

1.給str包裝一層對象實例
2.執行對象的一個特性
3.銷燬這層包裝實例

因此就不難理解,爲何上面會是undefined. (由於沒都沒了,你哪來的定義嘞)。
綜上所述,在js中一切都是對象是不無道理的。
還記得上面說的,對象是由 new + 構造器函數 建立的嗎? 因此說 有構造器的類型,都是對象。 事實上除了null,undefined 這兩個 呆毛。 其餘的類型都有構造器,因此再次聲明一切都是對象是頗有道理的。
最後咱們來回答一下開篇的那個題目,爲何函數也是對象?
若是函數也是對象,那他應該具備對象的一切特性,我這裏偷個懶,就舉他的動態特性吧。

function a (){};
a.move = 1;
console.log(a.move);  //1

額,不信嗎? 我開大了哈~ 用instanceof 檢測一下

console.log(a instanceof Object);   // true

完畢~再補充一點,我整篇都是對象對象的。英文不都是Object. 那爲何Function類型也是Object. RegExp類型也是Object. Object 也是Object. 好了 不繞了, 若是你們若是知道原型鏈這個東西的話,應該知道,全部的構造器的原型的金字塔尖 就是Object. (null不算啊~ 這個呆毛不算,由於Object再往上就是null了);下次面試以前理解一下這句話,我相信,你的評級應該會靠SP 更近一點吧。嘿嘿

相關文章
相關標籤/搜索