js深入理解构造函数和原型对象
1.在典型的oop的語言中,如java,都存在類的概念,類就是對(duì)象的模板,對(duì)象就是類的實(shí)例。但在js中不存在類的概念,js不是基于類,而是通過構(gòu)造函數(shù)(constructor)和原型鏈(prototype chains)實(shí)現(xiàn)的。但在ES6中引入了類(class)這個(gè)概念,作為對(duì)象的模板,新的class寫法知識(shí)讓原型對(duì)象的寫法更加清晰,這里不重點(diǎn)談這個(gè)
2.首先我們來詳細(xì)了解下什么是構(gòu)造器
構(gòu)造函數(shù)的特點(diǎn):
a:構(gòu)造函數(shù)的首字母必須大寫,用來區(qū)分于普通函數(shù)
b:內(nèi)部使用的this對(duì)象,來指向即將要生成的實(shí)例對(duì)象
c:使用New來生成實(shí)例對(duì)象
eg1:
1 function Person(name,age){ 2 this.name = name; 3 this.age = age; 4 this.sayHello = function(){ 5 console.log(this.name +"say hello"); 6 } 7 } 8 9 var boy = new Person("bella",23); 10 boy.sayHello(); // bella say hello構(gòu)造函數(shù)的缺點(diǎn):
所有的實(shí)例對(duì)象都可以繼承構(gòu)造器函數(shù)中的屬性和方法。但是,同一個(gè)對(duì)象實(shí)例之間,無法共享屬性
解決思路:
a:所有實(shí)例都會(huì)通過原型鏈引用到prototype
b:prototype相當(dāng)于特定類型所有實(shí)例都可以訪問到的一個(gè)公共容器
c:那么我們就將重復(fù)的東西放到公共容易就好了
eg2:
1 function Person(name,age){ 2 this.name = name; 3 this.age = age; 4 this.sayHello = function(){ 5 console.log(this.name + "say hello"); 6 } 7 } 8 var girl = new Person("bella",23); 9 var boy = new Person("alex",23); 10 console.log(girl.name); //bella 11 console.log(boy.name); //alex 12 console.log(girl.sayHello === boy.sayHello); //false
?
一個(gè)構(gòu)造函數(shù)Person生成了兩個(gè)對(duì)象實(shí)例girl和boy,并且有兩個(gè)屬性和一個(gè)方法。但是sayHello方法是不一樣的。如上圖(圖畫得很丑)。也就是說當(dāng)New一個(gè)實(shí)例對(duì)象的時(shí)候,都會(huì)去創(chuàng)建一個(gè)sayHello方法,這就浪費(fèi)了內(nèi)存資源,因?yàn)閟ayHello方法使一樣的行為的,完全可以被兩個(gè)實(shí)例對(duì)象共享。
所以,缺點(diǎn)就是:同一個(gè)構(gòu)造函數(shù)的對(duì)象實(shí)例之間無法共享屬性和方法。
為了解決構(gòu)造函數(shù)的這個(gè)缺點(diǎn),js提供了prototype屬相來解決該問題。
prototype屬性的作用
js中每個(gè)數(shù)據(jù)類型都是對(duì)象,除了null 和 undefined(這個(gè)可以參考另一篇將null 和 undefined的博客),而每個(gè)對(duì)象都是繼承自一個(gè)原型對(duì)象,只有null除外,它沒有自己的原型對(duì)象,最終的Object的原型為null
eg3:
1 function Person(name,age){ 2 this.name = name; 3 this.age = age; 4 } 5 Person.propotype.sayHello = function(){ 6 console.log(this.name + "say hello"); 7 } 8 var girl = new Person("bella",23); 9 var boy = new Person("alex",23); 10 console.log(girl.name); //bella 11 console.log(boy.name); //alex 12 console.log(girl.sayHello === boy.sayHello); //true View Code? ? ? ? ? ? ? ? ?
? ? ? 由上圖可以看出,prototype是構(gòu)造函數(shù)的屬性,而consructor則是構(gòu)造函數(shù)的prototype屬性所指向的那個(gè)對(duì)象,也就是說constuctor是原型對(duì)象的屬性。
constructor屬性是定義在原型對(duì)象上面,意味著也可以被實(shí)例對(duì)象繼承
eg4:
1 function Person(name,age){ 2 this.name = name; 3 this.age = age; 4 } 5 Person.propotype.sayHello = function(){ 6 console.log(this.name + "say hello"); 7 } 8 var girl = new Person("bella",23); 9 console.log(girl.construcotr); //Person() 10 console.log(girl.construcotr == Person.propotype.construcotr); //true View Code
constructor屬性的作用
a:分辨原型對(duì)象到底是哪個(gè)構(gòu)造函數(shù)
1 function Person(){}; 2 var person1 = new Person(); 3 console.log(person1.construcotr === Person); //true View Codeb:從實(shí)例新建另一個(gè)實(shí)例
1 function Person(){}; 2 var person1 = new Person(); 3 var person2 = new person1.construcotr(); 4 console.log(person2 instanceof Person); //true View Codec:由于constructor屬性是一種原型對(duì)象和構(gòu)造函數(shù)的關(guān)系,所以在修改原型對(duì)象的時(shí)候,一定 要注意construtor的指向問題,避免instanceof失真,關(guān)于這一點(diǎn),會(huì)在繼承中講到。
?
3.了解了構(gòu)造器,我們來看下原型prototype
JS中萬物都是對(duì)象,但是對(duì)象也分為:普通對(duì)象和函數(shù)對(duì)象,也就是Object 和 Function.
那么怎么區(qū)分普通對(duì)象和函數(shù)對(duì)象呢? ---凡是通過New Function()創(chuàng)建的對(duì)象都是函數(shù)對(duì)象,其他的都是普通對(duì)象.
需要注意的是:普通對(duì)象沒有propotype(prototype即是屬性也是對(duì)象),但是有__proto__屬性。
js創(chuàng)建對(duì)象的時(shí)候都有一個(gè)__propo__內(nèi)置屬性,用于指向創(chuàng)建它的函數(shù)對(duì)象的原型對(duì)象prototype。
我們還是來根據(jù)eg3的代碼來分析原型鏈
console.log(girl.__proto__ === Person.protype);//true
console.log(Persion.propotype.__proto__ === Object.propotype);//true
console.log(Object.porpotype.__proto__); //null
通過__proto__串起來直到Object.propotype.__proto__為null的鏈叫做原型鏈(矩形表示函數(shù)對(duì)象,橢圓形表示普通對(duì)象)
也許看到這個(gè)圖會(huì)有幾個(gè)疑問
a:為什么Object.__proto__指向Function.prototype?
Object是函數(shù)對(duì)象,是通過new Function()創(chuàng)建的,所以...
b:Function.__proto__ === Function.prototype //true
Function也是對(duì)象函數(shù),通過new Function()創(chuàng)建,所以...
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/thonrt/p/5900510.html
總結(jié)
以上是生活随笔為你收集整理的js深入理解构造函数和原型对象的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C# 控制台语音计算器
- 下一篇: QTP - 描述性编程