一、做用域鏈 -- 要到建立這個函數的那個做用域中取值——是「建立」,而不是「調用」node
若是代碼中只有聲明沒有賦值,顯示 undefined閉包
若是既無聲明也沒賦值,就會報錯函數
var a=10; function f1(){ var b=20; function f2(){ // 當前做用域沒有此變量時,逐級往父做用域上面找 var c = 30; console.log(a) // 自由變量 console.log(b) // 自由變量 console.log(c) } f2() } f1()
二、閉包this
閉包的使用場景spa
一、函數做爲返回值prototype
二、函數做爲參數傳遞-----要到建立這個函數的那個做用域中取值——是「建立」,而不是「調用code
function F1() { var a = 10; //若是這條代碼消失,a會取上一級做用域的值 console.log('b') return function () { console.log(a) // a 爲自由變量 } } var f1 = F1(); var a = 20; // f1(); // 10 function F2(fn){ var a=30; // a不會取調用它的做用域的值 fn() } F2(f1) // 10
三、原型鏈對象
在訪問對象的屬性和方法時, 會在當前對象中查找, 若是沒有找到, 會一直沿着原型鏈上的原型對象__proto__向上查找, 直到找到Object.prototype(原型的頂端)
爲止,這就是原型鏈。blog
function Dog() { this.eat = function () { console.log('喜歡吃骨頭') } } function Cat() { this.food = function () { console.log('喜歡吃魚') } } Cat.prototype.weight=function(){ console.log('不重') } Dog.prototype = new Cat(); var dog = new Dog(); dog.eat() // 喜歡吃骨頭 dog.food() // 喜歡吃魚 dog.weight() // Cat的原型對象的方法會被繼承下來