JS原型 原型鏈


跑在最前面的這段話:

1.JS對象分類:

簡單記憶:凡是通過new Function()創建的對象都是函數對象,其他均是普通對象。

2.只有函數對象才有prototype屬性,這個屬性是一個指針,指向一個對象(通過該構造函數創建實例對象的原型對象),該屬性的指向我們就可以叫做“原型”或者“原型對象”,即:

1 function Person() {};
2 Person.prototype;
3 //constructor:ƒ Person()
4 //__proto__:Object
 var A = Person.prototype;//將A記做原型對象

3.默認情況下,所有的原型或者原型對象都會自動獲得一個constructor(構造函數)屬性,該屬性(是一個指針)指向該函數的構造函數,即:

1 Person.prototype.constructor == Person

3.js對象均有一個_proto_屬性;但_proto_並非是一個規范屬性,只是部分瀏覽器實現了此屬性,對應的標准屬性是[[Prototype]];

  • 每個對象規定一個私有屬性[[prototype]],[[prototype]]所指向的對象也有一個[[prototype]]屬性;
  • 但是[[prototype]]語言使用者是無法訪問的,不過FirFox的js引擎將其暴露出來,作為公有屬性__proto__

4.函數對象和原型對象通過prototype和constructor屬性進行相互關聯;

5.constructor屬性

constructor屬性始終指向創建當前對象的構造函數。

 1     var arr=[1,2,3];
 2     console.log(arr.constructor); //function Array(){};
 3     var a={};
 4     console.log(arr.constructor);//function Object(){};
 5     var bool=false;
 6     console.log(bool.constructor);//function Boolean(){};
 7     var name="hello";
 8     console.log(name.constructor);//function String(){};
 9     var sayName=function(){}
10     console.log(sayName.constrctor)//function Function(){}
11     
12     //通過構造函數創建instance
13     function A(){}
14     var a=new A();
15     console.log(a.constructor);//function A();
 1    function Person(name){
 2         this.name=name;
 3     }
 4     Person.prototype.sayName=function(){
 5         console.log(this.name);
 6     }
 7     
 8     var person=new Person("lili");
 9     
10     console.log(person.constructor); // function Person(){}
11     console.log(Person.prototype.constructor);// function Person(){}
12     console.log(Person.constructor); // function Function(){}

 1.構造函數:

1 function Foo(name,age){
2   this.name = name;
3   this.age = age;
4   this.class = 'class-1';
5   //return this; //默認有這一行,因此不必自己寫
6 }
7 var f = new Foo('lili',22);

  

2.構造函數的擴展

先拋出一個名詞:語法糖

在計算機科學中,語法糖(syntactic sugar)是指編程語言中可以更容易的表達一個操作的語法,它可以使程序員更加容易去使用這門語言:操作可以變得更加清晰、方便,或者更加符合程序員的編程習慣。

簡單理解就是代碼的一種簡潔寫法,比如:

1 var a = {} 是 var a = new Object()的語法糖;
2 var a = [] 是 var a = new Array()的語法糖
3 function Foo(){...}   是var Foo = new Function(){..} 的語法糖

 

3.再拋出五條原型規則:

*所有的引用類型(數組、對象、函數)都具有對象特性,即可自由擴展屬性,除了“null”以外;

1 var arr=[];arr.a=100;
2 var obj = {};obj.a=200;
3 function fn(){};fn.a=300;
4 
5 console.log(arr);//[a: 100]
6 console.log(obj);//{a: 200}
7 console.log(fn.a);//200

*所有的引用類型(數組、對象、函數)都有一個__proto__屬性(也稱隱式原型屬性),屬性值是一個普通的對象;

1 var arr=[];arr.a=100;
2 var obj = {};obj.a=200;
3 function fn(){};fn.a=300;
4 
5 console.log(arr.__proto__);//[constructor: ƒ, concat: ƒ, pop: ƒ, push: ƒ, shift: ƒ, …]
6 
7 console.log(obj.__proto__);//{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
8 
9 console.log(fn.__proto__);//ƒ () { [native code] }

*所有的函數都有一個prototype屬性(也稱顯式原型屬性),屬性值也是一個普通的對象;

 1 var arr=[];arr.a=100;
 2 var obj = {};obj.a=200;
 3 function fn(){};fn.a=300;
 4 
 5 console.log(arr.__proto__);//[constructor: ƒ, concat: ƒ, pop: ƒ, push: ƒ, shift: ƒ, …]
 6 
 7 console.log(obj.__proto__);//{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
 8 
 9 console.log(fn.__proto__);//ƒ () { [native code] }
10 
11 console.log(arr.prototype);//undefined 沒有prototype屬性
12 
13 console.log(fn.prototype);//{constructor: ƒ}

*所有的引用類型(數組、對象、函數)的__proto__屬性(即隱式原型屬性)指向它的構造函數的" prototype " 屬性值(即顯顯式原型)(===)。

*當試圖得到一個對象的某個屬性時,如果這個對象本身沒有這個屬性,那么會在它的隱式原型屬性__proto__(即它的構造函數的prototype)中一直往上找尋找該屬性,但不會查找自身的prototype,(原型鏈的形成是真正靠_proto_而非prototype屬性);這也就是原型鏈的形成過程(下圖中的紅色線條表示的過程)

 1 //構造函數
 2 function Foo(name,age){
 3    this.name=name;
 4 }
 5 Foo.prototype.alertName = function(){
 6   alert(this.name);
 7 }
 8 //創建實例
 9 var f = new Foo('lili');
10 f.printName = function(){
11   console.log(this.name);
12 }
13 //test
14 f.printName();//lili
15 f.alertName();//lili

實例f中本身有個printName屬性,打印出來的console.log(this.name)自然就是創建時傳進去的"lili";而alertName屬性在構造函數Foo中並沒有,於是順着實列的隱式原型屬性__proto__(即其構造函數的prototype屬性)找,便找到了alert(this.name)這句。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM