1. 程式人生 > >JS概念理解(一)——函式和物件、原型鏈、_proto_

JS概念理解(一)——函式和物件、原型鏈、_proto_

        最近發現自己JS的基礎不太好,於是通過看書和大神的部落格,通過自己的理解將一些難懂的概念在此總結:

        1.函式和物件的關係:

        在JavaScript中一切物件都是通過函式建立的,某些情況下的寫法實際上是一種語法糖:

var a = {b : 20, c: 30};
var arr = [ 5 , "as", true];
//可以寫成
var a = new Object();
a.b = 20;
a.c = 30;
var arr = new Array();
arr[0] = 5;
arr[1] = "as";
arr[2] = true;
        上面這兩種寫法實際上可以互相替換,我們經常使用的上面這種寫法,因為更加簡便,可讀性更高,但是我們需要明白它們實際上也是通過函式建立的。

        2.Prototype原型鏈:

        在Java這類強型別語言當中,類在被建立好之後不允許再次新增其中的方法和屬性,就像是蓋印章,蓋下去是什麼就沒法改變了。而在JavaScript中,由於它是弱型別語言,可以隨時在程式中改變類中的方法和屬性。

var aa = {a:10 , b:true};
console.log(aa.toString());   //結果:[object Object]
var bb = [ 10,20];
console.log(bb.toString());   //結果:10,20
        從上面的程式碼段可以看出來,由於它們的物件型別不同,結果也大不一樣,是Array物件對Array.prototype.toString()進行了過載。

        如果我們想實現過載,也很簡單隻需要在繼承的子類的prototype中修改父類的方法就可以了,因為原型鏈是一個鏈式結構,當子類需要一個方法時他總是會先去找自己的類中有沒有該方法,如果沒有在去父類中尋找。

function People() {
    this.name = "srk";
this.age = 100;
}
People.prototype.speak = function () {
    console.log("hello person");
};
function Student() {}
Student.prototype = new People();   
//實現繼承 Student.prototype.speak = function () { console.log("hello student"); }; var p1 = new People(); var p2 = new Student(); p1.speak();//hello person p2.speak(); //hello student
最後再放一幅圖,很能說明JS原型鏈繼承的特點:


        3._proto_隱式原型

        每個物件都擁有一個隱藏屬性_proto_,該屬性引用了建立這個物件的函式的prototype,還用上個例子的程式碼來說的話,p1._proto_ === People.prototype,關係如圖所示:
        在這個圖當中,o1的_proto_指向了Object.prototype,因為它實際上就是一個Object物件,然而Object.prototype也擁有一個_proto_屬性,這個值為null。總而言之就是:物件的_proto_指向建立它的函式的prototype。