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]];編程語言
4.函數對象和原型對象經過prototype和constructor屬性進行相互關聯;函數
5.constructor屬性this
constructor屬性始終指向建立當前對象的構造函數。spa
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.構造函數:prototype
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)這句。