日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

构造函数、实例、原型对象、继承

發(fā)布時間:2024/9/27 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 构造函数、实例、原型对象、继承 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、構(gòu)造函數(shù)與原型對象之間的關(guān)系:

有一個Star構(gòu)造函數(shù),每一個構(gòu)造函數(shù)里面都有一個原型對象,是通過構(gòu)造函數(shù)的prototype指向這個原型對象的

同樣在這個原型對象里面也有一個屬性叫constructor,它又指回了構(gòu)造函數(shù)

可以把構(gòu)造函數(shù)看為是父親,父親通過prototype指向兒子原型對象,告訴別人看我有一個厲害的兒子叫原型對象,而原型對象里面又有一個屬性constructor,又指回了構(gòu)造函數(shù)說,看我有一個厲害的老爹,兩人互相吹捧了一番

二、構(gòu)造函數(shù)、實例對象與原型對象之間的關(guān)系:

我們可以通過構(gòu)造函數(shù)創(chuàng)建一個實例對象,只要new了構(gòu)造函數(shù)就可以產(chǎn)生一個實例對象,所以構(gòu)造函數(shù)又可以指向這個對象實例,我們知道在這個實例對象中也有一個原型__proto__,這個__proto__指向的是Star原型對象,當(dāng)然了我們對象實例里面也有一個constructor,它可以指回構(gòu)造函數(shù)

三、原型鏈

只要是對象就有__proto__原型,指向原型對象

原型對象里面的__proto__原型指向的是Object.prototype

function Star(uname,age){this.uname = uname;this.age = age; } Star.prototype.sing = function(){console.log("我會唱歌"); } var zxz = new Star('張信哲',18); // 只要是對象就有__proto__原型,指向原型對象 console.log(Star.prototype); console.log(Star.prototype.__proto__ === Object.prototype);// true // 我們Star原型對象里面的__proto__原型指向的是Object.prototype console.log(Object.prototype.__proto__); // 我們的Object.prototype原型對象里面的__proto__原型 指向為null

四、JavaScript對象成員查找機制(規(guī)則)

  • 當(dāng)訪問一個對象的屬性(包含方法)時,首先查找這個對象自身有沒有該屬性

  • 如果沒有就查找它的原型(也就是__proto__指向的prototype原型對象)

  • 如果還沒有就查找原型對象的原型(Object的原型對象)

  • 依次類推一直找到Object為止(null)

  • __proto__對象原型的意義就在于為對象成員查找機制提供一個方向或者說一條路線。

var that; function Star(name,age){ // 在構(gòu)造函數(shù)中,里面的this指向的是實例對象 this.name = name; this.age = age; } Star.prototype.sing = function(){ // 原型對象函數(shù)中的this,指向的是實例對象,mxq對象that = this;console.log("我會唱歌"); } // Star.prototype.sex = "女" Object.prototype.sex = "女" var mxq = new Star("萌小七",18) // mxq.sex = "女" console.log(mxq.sex);// 輸出女 mxq.sing(); console.log(that === mxq);// true 原型對象this指向:在構(gòu)造函數(shù)中,里面的this指向的是實例對象原型對象函數(shù)中的this,指向的是實例對象

五、利用原型對象擴展內(nèi)置對象

可以通過原型對象,對原來的內(nèi)置對象進行擴展自定義的方法。比如給數(shù)組增加自定義求偶數(shù)和的功能。

注:數(shù)組和字符串內(nèi)置對象不能給原型對象覆蓋操作Array.prototype = {},只能是Array.prototype.xxx = function(){}的方式。

Array.prototype.sum = function(){var total = 0for(var i=0;i<this.length;i++){total += this[i]}return total; } var arr = [5,6,7]; arr.sum(); // 18

六、繼承

ES6之前并沒有給我們提供extends繼承,我們可以通過構(gòu)造函數(shù)+原型對象模擬實現(xiàn)繼承,被稱為組合繼承,用原型鏈實現(xiàn)對原型屬性和方法的繼承,借用構(gòu)造函數(shù)技術(shù)來實現(xiàn)實例屬性的繼承。

1、借用構(gòu)造函數(shù)繼承父類型屬性

核心原理:通過call()把父類型的this指向子類型的this,這樣就可以實現(xiàn)子類型繼承父類型的屬性。

call() 作用:調(diào)用這個函數(shù)并且修改函數(shù)運行時this的指向

fun.call(thisArg,arg1,arg2,...)

thisArg:當(dāng)前調(diào)用函數(shù)this的指向?qū)ο?/p>

arg1,arg2:傳遞的其他參數(shù)

function fn(x,y){console.log(this);console.log("我想出去玩");console.log(x+y) } var obj = {name:"萌小七" } fn();// this指向的是window,我想出去玩 // call()可以調(diào)用函數(shù) fn.call();// this指向的是window,我想出去玩 // call() 可以改變這個函數(shù)的this指向,此時這個函數(shù)的this就指向了obj這個對象 fn.call(obj,1,2);// {name: "萌小七"} 我想出去玩 3

舉例說明:借用父構(gòu)造函數(shù)繼承屬性

function Father(name,age){// this指向父構(gòu)造函數(shù)的對象實例this.name = namethis.age = age } function Son(name,age,score){// this指向子構(gòu)造函數(shù)的對象實例Father.call(this,name,age)this.score = score } var son = new Son("小丸子",18,98) console.log(son); // 輸出:Son {name: "小丸子", age: 18, score: 98}

此時子構(gòu)造函數(shù)繼承了父構(gòu)造函數(shù)的屬性

2、利用原型對象繼承方法: Son.prototype = new Father();

function Father(name,age){// this指向父構(gòu)造函數(shù)的對象實例this.name = namethis.age = age } function Son(name,age,score){// this指向子構(gòu)造函數(shù)的對象實例,構(gòu)造函數(shù)來復(fù)制父類的屬性給Son實例Father.call(this,name,age)this.score = score } Father.prototype.money = function(){console.log("父親要掙錢") } // Son.prototype = Father.prototype // 這樣直接賦值會有問題,如果修改了子原型對象,父原型對象也會跟著一起改變 Son.prototype = new Father(); // 如果利用對象的形式修改了原型對象,別忘了利用constructor指回原來的原型對象 Son.prototype.constructor = Son Son.prototype.school = function(){console.log("孩子要上學(xué)") } var son = new Son("小丸子",18,98) console.log(son); console.log(Father.prototype);


優(yōu)點:

父類的方法可以被復(fù)用

父類的引用屬性不會被共享

子類構(gòu)建實例時可以向父類傳遞參數(shù)

缺點:

第一次調(diào)用Father():給Son.prototype寫入兩個屬性name,age。

第二次調(diào)用Father():給instance1寫入兩個屬性name,age。

實例對象son上的兩個屬性就屏蔽了其原型對象Son.prototype的兩個同名屬性。所以,組合模式的缺點就是在使用子類創(chuàng)建實例對象時,其原型中會存在兩份相同的父類實例的屬性/方法。這種被覆蓋的情況造成了性能上的浪費。


寄生組合繼承(最優(yōu)方案)
組合繼承會有兩次調(diào)用父類的構(gòu)造函數(shù)而造成浪費的缺點,寄生組合繼承就可以解決這個問題。

核心在于inheritPrototype(son, father),讓子類的prototype指向父類原型的拷貝,這樣就不會調(diào)用父類的構(gòu)造函數(shù),進而引發(fā)內(nèi)存的浪費問題。

function inheritPrototype(son, father) {// 修正子類原型對象指針,指向父類原型的一個副本 (用object()也可以) son.prototype = Object.create(father.prototype)// 增強對象,彌補因重寫原型而失去的默認的constructor屬性son.prototype.constructor = son } function Father(name,age){ // this指向父構(gòu)造函數(shù)的對象實例 this.name = name this.age = age } function Son(name,age,score){ // this指向子構(gòu)造函數(shù)的對象實例,構(gòu)造函數(shù)來復(fù)制父類的屬性給Son實例Father.call(this,name,age) this.score = score } Father.prototype.money = function(){console.log("父親要掙錢") } inheritPrototype(Son, Father) Son.prototype.school = function(){ console.log("孩子要上學(xué)") } var son = new Son("小丸子",18,98) console.log(son); console.log(Father.prototype);


【轉(zhuǎn)載】https://mp.weixin.qq.com/s/FZTgakDp-jQc1Ic4NT7WYg

總結(jié)

以上是生活随笔為你收集整理的构造函数、实例、原型对象、继承的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。