閉包
什么是閉包?閉包的作用?閉包的應(yīng)用?
答:
函數(shù)執(zhí)行,形成私有的執(zhí)行上下文,使內(nèi)部私有變量不受外界干擾,起到保護(hù)和保存的作用
作用:
- 保護(hù)
- 避免命名沖突
- 保存
- 解決循環(huán)綁定引發(fā)的索引問(wèn)題
-
變量不會(huì)銷毀
- 可以使用函數(shù)內(nèi)部的變量,使變量不會(huì)被垃圾回收機(jī)制回收
應(yīng)用:
- 設(shè)計(jì)模式中的單例模式
- for循環(huán)中的保留i的操作
- 防抖和節(jié)流
- 函數(shù)柯里化
缺點(diǎn)
- 會(huì)出現(xiàn)內(nèi)存泄漏的問(wèn)題
原型和原型鏈
什么是原型?什么是原型鏈?如何理解
答:
原型: 原型分為隱式原型和顯式原型,每個(gè)對(duì)象都有一個(gè)隱式原型,它指向自己的構(gòu)造函數(shù)的顯式原型。
原型鏈: 多個(gè)__proto__組成的集合成為原型鏈
- 所有實(shí)例的
__proto__都指向他們構(gòu)造函數(shù)的prototype - 所有的
prototype都是對(duì)象,自然它的__proto__指向的是Object()的prototype - 所有的構(gòu)造函數(shù)的隱式原型指向的都是
Function()的顯示原型 - Object的隱式原型是null
繼承
說(shuō)一說(shuō) JS 中的常用的繼承方式有哪些?以及各個(gè)繼承方式的優(yōu)缺點(diǎn)。
答:
原型繼承、組合繼承、寄生組合繼承、ES6的extend
原型繼承
// ----------------------方法一:原型繼承 // 原型繼承 // 把父類的實(shí)例作為子類的原型
// 缺點(diǎn):子類的實(shí)例共享了父類構(gòu)造函數(shù)的引用屬性 不能傳參
var person = { friends: ["a", "b", "c", "d"] } var p1 = Object.create(person) p1.friends.push("aaa")
//缺點(diǎn):子類的實(shí)例共享了父類構(gòu)造函數(shù)的引用屬性 console.log(p1); console.log(person);
//缺點(diǎn):子類的實(shí)例共享了父類構(gòu)造函數(shù)的引用屬性
組合繼承
// ----------------------方法二:組合繼承
// 在子函數(shù)中運(yùn)行父函數(shù),但是要利用call把this改變一下,
// 再在子函數(shù)的prototype里面new Father() ,使Father的原型中的方法也得到繼承,最后改變Son的原型中的constructor
// 缺點(diǎn):調(diào)用了兩次父類的構(gòu)造函數(shù),造成了不必要的消耗,父類方法可以復(fù)用
// 優(yōu)點(diǎn)可傳參,不共享父類引用屬性
function Father(name) {
this.name = name
this.hobby = ["籃球", "足球", "乒乓球"] }
Father.prototype.getName = function () { console.log(this.name); }
function Son(name, age) { Father.call(this, name) this.age = age }
Son.prototype = new Father()
Son.prototype.constructor = Son
var s = new Son("ming", 20)
console.log(s);
寄生組合繼承
// ----------------------方法三:寄生組合繼承
function Father(name) {
this.name = name
this.hobby = ["籃球", "足球", "乒乓球"] }
Father.prototype.getName = function () {
console.log(this.name); }
function Son(name, age) {
Father.call(this, name)
this.age = age }
Son.prototype = Object.create(Father.prototype)
Son.prototype.constructor = Son
var s2 = new Son("ming", 18)
console.log(s2);
extend
// ----------------------方法四:ES6的extend(寄生組合繼承的語(yǔ)法糖)
// 子類只要繼承父類,可以不寫 constructor ,一旦寫了,則在 constructor 中的第一句話
// 必須是 super 。
class Son3 extends Father {
// Son.prototype.__proto__ = Father.prototype constructor(y) {
super(200)
// super(200) => Father.call(this,200)
this.y = y } }