js的作用域链,原型链,以及闭包函数理解
代碼一:
this.number = 10 function a() {this.number = 20 } a.prototype.init = () => console.log(this.number)const test = new a() // 構造函數生成一個獨立新對象 test.init() // 10解析:之所以輸出10,可以把 arrow function(箭頭函數) 里的 this 和 arguments 關鍵字理解為函數作用域里的變量(因為自身沒有),他訪問變量沿著作用域鏈向上找而不是直接訪問對象屬性走原型鏈,代碼中的init上頭的作用域就是window,所以他的this指向window.
注:可以試試把上例代碼中的箭頭函數換成普通匿名函數(輸出就是直接走原型鏈訪問對象屬性,number = 20)
代碼二:
this.number = 10 function a(){ //閉包函數return {show: () => console.log(this.number) } } a().show() // 10 函數a的this的指向window a.call({number: 20}).show() // 20 call改變了函數a的this指向,箭頭函數的作用域指向改變后的函數作用域 a.call({number: 30}).show() // 30解析:閉包函數里return出的箭頭函數被調用的時候會一直引用外層函數的變量this或者arguments,所以外層函數this指向被改變,return出的箭頭函數里的this也改變了.
this的指向可理解為兩大類:
1:test();==test.call(window,參數);//直接調用函數,this指向window
2:obj.test(); == obj.test.call(obj,參數);//函數作為對象的方法被調用,this指向該對象
注:this指向是在被調用時分配的
代碼三:
function a() {this.say = function() {console.log(1) } } a.prototype.say = function() { console.log(2) } var test = new a() test.say() // 1只有函數有prototype,對象對應_proto_,prototype可以對主函數進行擴充,但不會覆蓋主函數內的方法(如果主函數里沒有此對象屬性就在原型鏈里查找)。
簡單一句話~js中訪問變量沿著作用域鏈向上走(this),直接訪問對象上的屬性沿著原型鏈往下走~(都是就近查找哦)
對call和apply做補充:
相同點:都是為了改變對象this指向,參數二不同:call是傳進單個參數,apply是數組形式
apply可以接受一個數組或者類數組對象,console.log(...arguments) === console.log.apply(this,arguments)
?
轉載于:https://www.cnblogs.com/xiaoxiao666/p/8350617.html
總結
以上是生活随笔為你收集整理的js的作用域链,原型链,以及闭包函数理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 虚拟货币是什么
- 下一篇: 股票成交量红色和绿色代表什么意思