js難點(diǎn)之原型,真難?

構(gòu)造函數(shù)的首字母必須大寫,用來區(qū)分于普通函數(shù);
這里的this指向?qū)嵗蟮膶ο髉;

   function P(name) {
        this.name=name;
        this.say=function(){
            console.log("我是"+this.name)//我是毛敏;
        }
    }
    P.prototype.money="一百萬";
    P.prototype.name="maomin";
    var p=new P("毛敏");//實(shí)例化
    alert(p.name);
    p.say();//使用這個(gè)方法
    console.log(p.name+"有"+p.money)



所以有兩種方法:
1.通過構(gòu)造函數(shù)在函數(shù)內(nèi)直接this打點(diǎn),相當(dāng)于創(chuàng)建一個(gè)屬性。
2.通過給構(gòu)造函數(shù)一個(gè)prototype。(只有構(gòu)造函數(shù)才有prototype屬性)
注意實(shí)例化后的對象沒有prototype,如:p.prototype.a=“123”;console.log(p.a);這樣是錯(cuò)誤的。只有函數(shù)對象才有prototype.那么什么是函數(shù)對象,凡是通過new Function創(chuàng)建的對象就叫做函數(shù)對象。函數(shù)對象可以創(chuàng)建普通對象,但是普通對象不能創(chuàng)建函數(shù)對象。通常普通對象是通過Object創(chuàng)建的。
javascript中,每個(gè)對象都會(huì)在內(nèi)部生成一個(gè)proto 屬性,當(dāng)我們訪問一個(gè)對象屬性時(shí),如果這個(gè)對象不存在就回去proto 指向的對象里面找,一層一層找下去,這就是javascript原型鏈的概念。
p.proto ==> P.prototype ==> P.prototype.proto ==> Object.prototype ==> Object.prototype.proto ==>null
JS中所有的東西都是對象,所有的東西都由Object衍生而來, 即所有東西原型鏈的終點(diǎn)指向null
1、每一個(gè)函數(shù)對象都有一個(gè)prototype屬性,但是普通對象是沒有的;
  prototype下面又有個(gè)construetor,指向這個(gè)函數(shù)。
2、每個(gè)對象都有一個(gè)名為_proto_的內(nèi)部屬性,指向它所對應(yīng)的構(gòu)造函數(shù)的原型對象,原型鏈基于_proto_;
好了,開始上代碼和例子,建一個(gè)普通對象,我們可以看到
1、p的確沒有prototype屬性
2、p是P的實(shí)例
3、p的__proto__指向P的prototype
4、Object.prototype.constructor指向Object本身

 P.prototype.job=function(){
        console.log("我是一名前端工程師");
    }
    var data={
        "age":"21",
        "gender":"boy"
    }
    p.job();//我是一名前端開發(fā)工程師;
    console.log(data.age)
    alert(p.name)//會(huì)彈出毛敏,而不會(huì)彈出maomin,函數(shù)對象本身的屬性或方法的優(yōu)先級要高于原型的屬性或方法。
    console.log(P.__proto__.constructor);//Function()
    console.log(P.prototype.__proto__.constructor);//Object()



這里我們來總結(jié)一下prototype與_proto_之間的關(guān)系
new F().proto === F.prototype // true
前者是實(shí)例化的對象,后者是函數(shù)對象。

因?yàn)镺bject是一個(gè)函數(shù),函數(shù)的構(gòu)造器都是Function
Object.proto === Function.prototype // true

通過函數(shù)字面量定義的函數(shù)的__proto__屬性都指向Function.prototype
(function(){}).proto === Function.prototype // true

通過對象字面量定義的對象的__proto__屬性都是指向Object.prototype
({}).proto === Object.prototype // true

Object函數(shù)的原型的__proto__屬性指向null
Object.prototype.proto === null // true

因?yàn)镕unction本身也是一個(gè)函數(shù),所以Function函數(shù)的__proto__屬性指向它自身的prototype
Function.proto === Function.prototype // true

因?yàn)镕unction的prototype是一個(gè)對象,所以Function.prototype的__proto__屬性指向Object.prototype
Function.prototype.proto === Object.prototype // true

下面的代碼是又重新闡述了_proto_的屬性。

        var a={};
        a.__proto__.name="maomin";
        console.log(a.__proto__.constructor);//Object()
        console.log(a.name)
        var b=function(){};
        console.log(b.__proto__.constructor);//Function()
        var c=String();
        console.log(c.__proto__.constructor);//String()
        //通過上面幾個(gè)數(shù)據(jù)類型的演示,知道了__proto__是每個(gè)對象都有的屬性。


        function A(name) {
            this.name=name
        }
        var a=new A("maomin")
        console.log(a.constructor)




作者:Vam的金豆之路

主要領(lǐng)域:前端開發(fā)

我的微信:maomin9761

微信公眾號:前端歷劫之路