先附上原型鏈的圖,能看懂的本文就沒必要看了,看不懂的可以帶着疑問看文章
一、構造函數
什么是構造函數:當一個普通函數創建一個類對象是,那么就程它為構造函數。
特點:
默認首字母大寫
使用new關鍵字來調用,並返回一個實例對象
內部使用this來構造屬性和方法
this指向返回的新對象
function Person(name){ this.name = name this.eat = function(){ console.log("方法") } } let per = new Person("小小") per.eat()
二、原型
為什么需要原型:在一些場景中,比如人類行為有些要打游戲,有些要上學,有些要工作,但同時他們都需要吃飯和睡覺,但如果把每個人吃飯睡覺私有化使用的話就有點浪費內存,這時候就可以把這些每個人都需要做的行為統一拿出來放到一個公共的空間,每個人都有權限訪問它,這樣就可以節省內存。而實現共享的,這個時候就用到了原型 prototype。
什么是原型:每個函數對象都有一個prototype屬性,這個屬性的指向被稱為該函數對象的原型對象,簡稱原型。
function Person(name){ this.name = name // this.eat = function(){ // console.log("飯") // } } Person.prototype={ constructor:Person, //修改constructor的指向 eat:function(){ console.log("飯") }, sleep:function(){ console.log("睡覺") } } var per = new Person("小小") var Per = new Person("大大") console.log(per.eat === Per.eat) //true
以上案例我們看到Person的方法寫到原型中的時候,實例化后的對象拿到的方法是共享的。
構造函數的prototype原型,實例對象可以直接訪問,Person.prototype === per.__proto__
constructor是什么:
constructor 是實例對象和原型對象下的一個隱藏屬性,指向構造函數
per.constructor === Person
Person.prototype.contructor === Person
三、原型鏈:
什么是原型鏈:實例對象與原型的連接關系,被稱為原型鏈。
function Person(name){ this.name = name } Person.prototype={ constructor:Person, eat:function(){ console.log("飯") }, sleep:function(){ console.log("睡覺") } } var per = new Person("小小") console.dir(Person) console.log(per) console.log(per.__proto__ === Person.prototype) //true console.log(per.__proto__.__proto__ === Person.prototype.__proto__) //true console.log(Person.prototype.__proto__ === Object.prototype) //true
//---------------------------------------------------- console.log(Person.__proto__ === Function.prototype) //true console.log(Person.__proto__.__proto__ === Function.prototype.__proto__) //true console.log(Function.prototype.__proto__ === Object.prototype) //true
簡單描述:
實例對象per的__proto__ 等於構造函數的prototype,per是Person的實例對象
Person.prototype原型對象的__proto__等於構造函數Object的prototype,Person.prototype是Object的實例對象
由此可見存在一個Object構造函數,同時Object也是Function的實例對象。
Object.prototype.__proto__ ===null
Object.__proto__ === Function.prototype
---------------------------------------------------------
構造函數Person是Function的實例對象
Function.prototype是Object的實例對象
4、new的原理
從上面案例中我們能看出實例對象是通過new構造函數而得到,從而建立了實例對象與原型的關系
這里我們猜想下new都做了什么?
1、接收一個函數方法體和參數
2、返回一個新對象
3、函數方法下的this指向新的對象
4、把新對象的__proto__指向構造函數的原型
簡易版new
function Mynew(fn,...args){ if(typeof fn !== "function"){ throw "第一個參數必須是方法體" } let obj = {} obj.__proto__ = Object.create(fn.prototype) fn.apply(obj,args) return obj } let mynew = Mynew(Person,"哈哈") console.log(mynew.name) mynew.sleep()