javascript欄位介紹面試必會的原型與繼承
#相關免費學習推薦:javascript(影片)
本文從以下幾個面向著手
- 0怎麼理解物件導向
- 1建立物件的方式
- 2記住原型鏈的小技巧
- #3instanceof 模擬實作
- 4new關鍵字模擬實作
- 5繼承的實作(逐步實作)
0 怎麼理解物件導向
其實我也不知道咋回答這問題,我只知道,面試官問這個後,就表示他要問一堆繼承的問題了。以下是引用週老師的一段說詞。
"物件導向是一種程式設計思想與面向過程是對應的一般的語言都是物件導向的js本身也是基於物件導向建構出來的,例如js本身就有很多內建類,Promise就是,可以new Promise來建立一個實例,來管理非同步程式設計。還有vue 也是,平常都是建立vue的實例啊。"
1 建立物件的方式
##1.物件字面量var o1 = {name: 'o1'} var o2 = new Object({name: 'o2'})2.透過建構子
var M = function(name){ this.name = name } var o3 = new M('o3')3.Object.create
var o4 = Object.create(p)2 記住原型鏈的小技巧##記憶總是有規律的,如高中時期學的三角函數,需要背公式很多,強行去背全部的公式是容易混亂的。不過如果把核心的幾點背牢,其餘的公式只需要稍加推導即可。關於原型鏈也是一樣,有幾點在開始就記住的話,後面就不會亂了。原型鏈中關鍵概念:
建構子實例(物件)有,實例, constructor ,__ proto__ ,prototype, 首先要記住他們的關係
- proto
- , 實例(物件)沒有prototype建構子有prototype ,同時prototype又是對象,那麼prototype即滿足上面一條,除了擁有 proto
- 外,還含有constructor構造函數的prototype的constructor就是指向構造函數本身,即上例中M.prototype. constructor === M
其實
建構子, 實例, constructor, __ proto__, prototype 的關係已經在上面的例子和3點介紹中介紹完了。不妨再回顧一下
- 建構子即普通函數,只不過前邊有new 關鍵字
- 透過
- new
加建構函式 ,產生的物件即為實例。
以上面產生o3實例為例子 -
o3.__proto__ === M.prototype //true o3.prototype //undefined o3.__proto__ === M.prototype //true
#o3實例本身並無constructor,不過會藉助原型鏈向上查找,即, -
o3.constructor === M.prototype.constructor // true o3.constructor === M //true
3 instanceof 模擬實作
instanceof 的原理是什麼呢?先來看看使用
[] instanceof Array // true
即左邊是對象,右邊是類型,instanceof 就是要判斷右邊類型的prototype,是否在左邊實例的原型鏈上,如下例子所示
[].__proto__ === Array.prototype //true Array.prototype.__proto__ === Object.prototype //true Object.prototype__proto__ //null#那麼依據這個想法來實現一下instanceof吧,一定會印象更加深刻
new的過程發生了什麼?function myInstanceof2(left, right){ if(left === null || left === undefined){ return false } if(right.prototype === left.__proto__) { return true } left = left.__proto__ return myInstanceof2(left, right) } console.log(myInstanceof2([], Array))4 new 模擬實現(簡要版)
- 產生空物件
- 這個空物件的
- proto
賦值為建構子的prototype
綁定this指向 - 回傳這個物件
-
// 构造函数 function M(name){ this.name = name } // 原生new var obj = new M('123') // 模拟实现 function create() { // 生成空对象 let obj = {} // 拿到传进来参数的第一项,并改变参数类数组 let Con = [].shift.call(arguments) // 对空对象的原型指向赋值 obj.__proto__ = Con.prototype // 绑定this //(对应下面使用来说明:Con是参数第一项M, // arguments是参数['123'], // 就是 M方法执行,参数是'123',执行这个函数的this是obj) let result = Con.apply(obj, arguments) return result instanceof Object ? result : obj } var testObj = create(M, '123') console.log('testObj', testObj)
5 繼承的實作(逐步實作)
- #建構方法核心Parent1.call(this)
-
// 构造方法方式 function Parent1(){ this.name = 'Parent1' } Parent1.prototype.say = function () { alert('say') } function Child1(){ Parent1.call(this) this.type = 'type' } var c1 = new Child1() c1.say() //报错
##思考: 為什麼call 實現了繼承,call本質是什麼?
只借助原型繼承核心Child2.prototype = new Parent2()
- 缺點: c21.arr 與c22.arr對應的是同一個引用
// 原型 function Parent2(){ this.name = 'Parent2' this.arr = [1,2] } Parent2.prototype.say = function () { alert('say') } function Child2(){ // Parent2.call(this) this.type = 'type' } Child2.prototype = new Parent2() var c21 = new Child2() var c22 = new Child2() c21.say() c21.arr.push('9') console.log('c21.arr : ', c21.arr) console.log('c22.arr : ', c22.arr)
思考:為什麼這麼寫是同一個引用?
組合繼承1
- 把上面兩個繼承方式的優點合併起來,缺點都拋棄掉
function Parent3(){ this.name = 'Parent3' this.arr = [1,2] } Parent3.prototype.say = function () { alert('say') } function Child3(){ Parent3.call(this) this.type = 'type' } Child3.prototype = new Parent3() var c31 = new Child3() var c32 = new Child3() c31.say() c31.arr.push('9') console.log('c31.arr : ', c31.arr) console.log('c31.arr : ', c32.arr)思考: 這麼寫就沒有問題了嗎?
答 : 生成一个实例要执行 Parent3.call(this) , new Child3(),也就是Parent3执行了两遍。
- 组合继承2
改变上例子 的
Child3.prototype = new Parent3()
为
Child3.prototype = Parent3.prototype
缺点 : 很明显,无法定义子类构造函数原型私有的方法
-
组合继承优化3 再次改变上例子 的
Child3.prototype = Parent3.prototype
为
Child3.prototype = Object.create(Parent3.prototype)
问题就都解决了。 因为Object.create的原理是:生成一个对象,这个对象的proto, 指向所传的参数。
思考 :是否还有疏漏?一时想不起来的话,可以看下这几个结果
console.log(c31 instanceof Child3) // true console.log(c31 instanceof Parent3) // true console.log(c31.constructor === Child3) // false console.log(c31.constructor === Parent3) // true
所以回想起文章开头所说的那几个需要牢记的点,就需要重新赋值一下子类构造函数的constructor: Child3.prototype.constructor = Child3,完整版如下
function Parent3(){ this.name = 'Parent3' this.arr = [1,2] } Parent3.prototype.say = function () { alert('say') } function Child3(){ Parent3.call(this) this.type = 'type' } Child3.prototype = Object.create(Parent3.prototype) Child3.prototype.constructor = Child3 var c31 = new Child3() var c32 = new Child3() c31.say() c31.arr.push('9') console.log('c31.arr : ', c31.arr) console.log('c31.arr : ', c32.arr) console.log('c31 instanceof Child3 : ', c31 instanceof Child3) console.log('c31 instanceof Parent3 : ', c31 instanceof Parent3) console.log('c31.constructor === Child3 : ', c31.constructor === Child3) console.log('c31.constructor === Parent3 : ', c31.constructor === Parent3)
5 es6的继承
class Parent{ constructor(name) { this.name = name } getName(){ return this.name } } class Child{ constructor(age) { this.age = age } getAge(){ return this.age } }
es6继承记住几个注意事项吧
- 1 构造函数不能当普通函数一样执行 Parent() 是会报错的
- 2 不允许重定向原型 Child.prototype = Object.create(Parent.prototype) 无用
- 3 继承写法如下,上面的Child类想继承父类,改成如下写法就好
注意写了extends关键字,constructor中就必须写super()
,打印结果如下:
以上是javascript原型和繼承是面試必會的的詳細內容。更多資訊請關注PHP中文網其他相關文章!

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3 Linux新版
SublimeText3 Linux最新版

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

Atom編輯器mac版下載
最受歡迎的的開源編輯器