javascript
JS学习笔记5
全局變量:
????????定義:可以提供給所有代碼塊和函數調用
私有變量:
????????定義:在js下,只有函數里定義的變量才是私有的 ? ?//在函數中調用可以,但在函數外邊調用不到????????//只有function中的變量獲得不到,其余代碼塊都可以獲取到
?? ? ?基本數據類型:null,undefined,number,string,bollean
?? ? ?引用數據類型:object
?? ? ?棧中存放基本變量,棧是先進后出
?? ? ?堆中存放引用類型對象,通過棧中的地址找到堆中的數據,堆是無序的,function也存在堆中
變量提升和作用域
?? ? ? 域解釋(變量提升):在當前的作用域中,js代碼執行之前,瀏覽器首先會把帶var和function的聲明內容,進行提前聲明或定義
?? ? ? ? var a ? //聲明告知瀏覽器在內存中存儲一個變量
?? ? ? ? var b=11//定義:不但定義了變量,還進行了賦值
變量提升的函數和變量的區別
?? ? ? ? var在內存中只完成了聲明
?? ? ? ? function在內存中完成了聲明和定義,只是函數沒調用時存儲的是字符串
?? ?例如:
?? ? ? ? console.log(a) //輸出undefined
?? ? ? ? var a =11
?? ? ? ? fun() //函數未執行前已經完成聲明和定以了,且將函數體轉換成字符串
? ? ? ? ? ? ? ? ? ? ? ? ? ? //在輸出的時候就會輸出該function的函數體轉換成的字符串
? ? ? ? ? ??? ? ? ? ?function fun(){
? ? ? ? ? ? ? ? ? ? ? console.log("這是函數")
? ? ? ? ? ??? ??? ? }
?? ?變量提升注意事項
?? ??? ?1.不定義var的區別:
?? ??? ? ? ? console.log(a) //輸出undefined
? ? ? ? ? ? ?console.log(b) //報錯,沒有變量提升的過程
?? ??? ? ? ? var a=11
?? ??? ? ? ? b=22 ??
?? ??? ?2.不管條件是否成立,都要進行變量提升
?? ??? ? ? ? console.log(a) //輸出undefined變量還存在
?? ??? ? ? ? if(false){
?? ??? ? ? ? ? ? ?var a=12
?? ??? ? ? ? }
?? ??? ?3.當執行一個匿名函數的時候,是不進行域解釋的,代碼的執行和定義一起完成了
?? ??? ? ? ? (function(){
?? ??? ? ? ? ? ? ?var a=b=3 ? ?//var b=3,a=b所以a沒有變量提升
?? ??? ? ? ? })()
?? ??? ? ? ? console.log(b) //輸出3,b變量提升了
?? ??? ? ? ? console.log(a)//報錯,沒有變量提升的過程
?? ??? ?4.當函數里的return語句執行時,下面的語句雖然不執行但是也需要變量提升
?? ??? ?注意:函數作用域下,有私有變量找私有變量,沒有形參找全局變量,但是如果形參和私有變量有了變量提升,就不會找全局變量了
?? ??? ? ? ? function fun(a){
?? ??? ? ? ? ? ?console.log(a)
? ? ? ? ? ? ? ? ? ? ? return false
?? ??? ? ? ? ? ?var a=66
?? ??? ? ? ? }
?? ??? ? ? ? fun()?
?? ??? ?5.在js中,變量和函數名稱重復,也沖突,在變量提升時,如果名稱聲明過了,不會再次聲明,但是可以重新賦值
?? ??? ?function num(){
? ? ? ? ? ? ? ??? ??? ??? ?console.log(111)
? ? ? ? ? ? ?? ??? ?}
? ? ? ? ? ? ?? ??? ?num()
? ? ? ? ? ? ?? ??? ?var num=66
?? ??? ?console.log(num)//輸出66,var不會重新聲明,但是可以改變值
?? ??? ?num() //報錯
垃圾回收
?? ?js具有自動垃圾回收機制,無需手動清除
?? ?標記清除
?? ? ? ? 原理:當js中聲明一個變量的時候,將變量標為“進入環境”,則變量在內存中占有位置,當變量執行完畢,會將其標記為“離開環境”js垃圾回收機制檢測到“離開環境”就會自動回收
在標準瀏覽器下常用這個回收方式,只是時間間隔不一樣
?? ?引用計數
?? ? ? ? 原理:js會跟蹤每一個變量的引用次數,當變量被聲明,并將一個值賦給變量,則引用計數會標注為1,如果變量執行元素或有進行了賦值,則引用計數進行加1,相反,變量賦給其他變量,或者沒再進行操作,則次數減1,直到次數變為0,則回收銷毀
如果出現循環引用,a調用b,b調用a,則內存會一直沒有釋放,容易出現內存泄漏
?? ?內存泄漏和溢出的區別
?? ? ? 內存泄漏:動態給內存分配空間,在使用完畢之后,沒有進行釋放,直到程序結束
?? ? ? 內存溢出:不顧堆棧分配的數據大小,向內存寫入過多的數據,導致數據越界
?? ?棧和堆的銷毀方式
?? ??? ?棧內存
?? ??? ? ? ? ?全局變量:只有瀏覽器關閉的時候才會回收
?? ??? ? ? ? ?局部變量:只有定義在函數里的才是局部變量,函數會產生自己的作用域,當函數執行完畢時,js內存機制會自動進行釋放
?? ??? ?堆內存
?? ?對象或函數在堆內存開辟空間,堆內存就會生成一個引用地址,如果有代碼引用了這個地址,則對象不會被銷毀。
如果想銷毀,需要把引用設置成null即可
?? ?例如:
? ?? ??? ?varx=new Array()
?? ??? ?x=null//銷毀了
?? ?不被銷毀特殊情況
?? ??? ?1、函數執行時,返回了一個對象,并在函數外調用,則私有變量不會被銷毀
??? ??? ??? ?function fun(){//延長作用域鏈
?? ??? ??? ? ? ? ? ? ? ?var x=[1,2,3]
?? ??? ??? ? ? ? ? ? ? ?return x
?? ??? ??? ? ? ? ? ?}
?? ??? ??? ? ? ? ? ?var arr=fun()
?? ??? ??? ? ? ? ? ?console.log(arr)//數組可以在函數內訪問,不會被銷毀
?? ??? ?2、在一個私有作用域中,給dom元素綁定事件,這個私有作用域不被銷毀
?? ??? ??? ?var btn=document.getElementById("btn")
?? ??? ? ? ? ? ? ? ??? ??? ?btn.οnclick=function(){
??? ??? ??? ? ? ? ? ? ? ? ??? ?var num=11
?? ??? ? ? ? ? ? ? ? ? ??? ?alert(num)
?? ??? ??? ? ? ? ? ? ? ?}
?? ?3、閉包(特殊作用域)
?? ??? ?閉包是能夠有權訪問其他函數內部的私有變量的函數,可以理解為函數嵌套函數。
?? ??? ?必須滿足以下特點,缺一不可:
?? ??? ??? ?1、函數嵌套函數
?? ??? ??? ?2、內部函數訪問外部函數的變量
?? ??? ??? ?3、變量不會被垃圾機制所回收
?? ??? ?例如:
?? ??? ??? ?function fun(){
?? ??? ??? ? ? ? ? ? ? ? ? ? ?var a=22
?? ??? ??? ? ? ? ? ? ? ? ? ? ?console.log("fun")
?? ??? ??? ? ? ? ? ? ? ? ? return ?function (){
?? ??? ??? ??? ?var b=1
??? ??? ??? ??? ?return ++a+(++b)
?? ??? ??? ??? ? ? ? ? ? ? ?}
?? ??? ??? ??? ? ? ? ?}
?? ??? ??? ? ? ? ? ? ? ? var f=fun()
?? ??? ??? ? ? ? ? ? ? ? var v2=f()
?? ??? ??? ? ? ? ? ? ? ? console.log(v2)//14
??? ??? ??? ? ? ? ? ? ? ?var v3=f()
?? ??? ??? ? ? ? ? ? ? ? console.log(v3)//15
?? ?注意:fun只執行一次,a不被銷毀,閉包執行多選,b每次執行都重新賦值成了1
?? ?閉包的作用:
?? ??? ?1、可以模擬私有方法
?? ??? ?2、用來實現對象的封裝
?? ??? ?3、用閉包可以訪問緩存(存在本地的),當代碼執行時間過長,可以先從緩存中讀取
面向對象
?? ??? ?對象:現實中一切事物都叫做對象
?? ??? ?面向對象的實體:包含屬性和行為的集合
?? ??? ?js沒有類的概念,叫做對象,思想上是基于對象,js下定義對象還是用函數體定義
?? ??? ?基于對象和面向對象的區別
?? ??? ? ? 面向對象:自己設置圖紙,照著圖紙蓋房子
?? ??? ? ? 基于對象:別人有一個房子,我照著房子創建
?? ??? ?面向對象的三大特征:封裝、繼承、多態
?? ??? ? ? 封裝:每一個對象就是一個封裝,把具有共同屬性和行為的事物放在一起
?? ??? ?定義對象
?? ??? ? ? ? 1.通過object創建
?? ??? ??? ?var p =new Object()
?? ??? ??? ?p.name="小明" ? ? //創建變量
?? ??? ??? ?p.say=function(){ ?//創建方法
?? ??? ??? ? ? ? ? ? ? ?console.log(p.name,p.age)
?? ??? ??? ? ? ? ? ?}
?? ??? ??? ? ? ? ? ?p.say() ?//調用方法
?? ??? ? ? ? 2.簡寫
?? ??? ? ? ??? ?var p={
?? ??? ? ? ??? ? ? ? ? ? ? ?name:"小明",
?? ??? ? ? ??? ? ? ? ? ? ? ?age:23,
?? ??? ? ? ??? ? ? ? ? ? ? ?say:function(){
?? ??? ? ? ??? ? ? ? ? ? ? ? ? ?console.log(this.name,this.age) ? ? ?//this表示調用當前對象的屬性
?? ??? ? ? ??? ? ? ? ? ? ? ?}
?? ??? ? ? ??? ? ? ? ? ?}
?? ??? ? ? ??? ? ? ? ? ?p.say()
?? ??? ?屬性操作
?? ??? ? ? ? configurable 是否可以通過delete刪除
?? ??? ? ? ? enumerable 是否可以通過for-in進行遍歷
?? ??? ? ? ? writable 是否可以修改屬性
?? ??? ? ? ? value 給屬性添加默認值
?? ??? ? ? ? get 獲取屬性的方法
?? ??? ? ? ? set 設置屬性的方法
?? ??? ? ? ? 思想:限定陌生人不能操作,但是自己可以通過get和set方法訪問
?? ??? ? ? ? 例如:
?? ??? ??? ?var obj={name:"小明",age:22}
?? ??? ??? ?//對象的屬性限定
?? ??? ??? ?Object.defineProperty(obj,"name",{
?? ??? ??? ??? ?configurable:false,?
?? ??? ??? ??? ?writable:false, ?
?? ??? ??? ??? ?value:"小藍" ?
?? ??? ??? ? ? })
?? ??? ??? ?設置get和set
?? ??? ??? ??? ?var obj={_name:"小明",age:22}
?? ??? ??? ??? ?Object.defineProperty(obj,"name",{
?? ??? ??? ??? ??? ?get:function(){ ?//獲得變量
?? ??? ??? ??? ??? ??? ?return this._name+"111"
?? ??? ??? ??? ??? ?},
?? ??? ??? ??? ??? ?set:function(name){ ?//修改變量
?? ??? ??? ??? ??? ??? ?this._name=name
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?})
?? ??? ??? ?設置多個屬性
?? ??? ??? ??? ?var obj={_name:"小明",age:22}
?? ??? ??? ??? ?Object.defineProperties(obj,{
?? ??? ??? ??? ??? ?name:{writable:false},
?? ??? ??? ??? ??? ?age:{enumerable:false}
?? ??? ??? ??? ?})
?? ??? ?自己創建get和set方法
?? ??? ??? ?var obj={
? ? ? ? ? ? ?? ??? ??? ??? ?name:"小明",
? ? ? ? ? ? ?? ??? ??? ??? ?getName:function(){return this.name},
? ? ? ? ? ? ?? ??? ??? ??? ?getAge:function() {return this.age},
? ? ? ? ? ? ?? ??? ??? ??? ?setName:function(name){ //有this的是對象里邊的變量,沒有是外界的變量
? ? ? ? ? ? ?? ??? ??? ??? ? ? ? this.name=name
? ? ? ? ? ? ?? ??? ??? ??? ?},
? ? ? ? ? ? ?? ??? ??? ?}
? ? ? ? ? ? ?? ??? ??? ?console.log(obj.getName(),obj.getAge())
構造器
????????用來給對象賦初始值,構造器是一種特殊的函數,如果不寫,js會自動分配一個默認無參的構造器
?? ??? ??? ?例如:
?? ??? ??? ??? ?function Emp(name,age){ ?//構造器
?? ??? ??? ??? ??? ?this.name=name
?? ??? ??? ??? ??? ?this.age=age
?? ??? ??? ??? ??? ?this.say=function(){
?? ??? ??? ??? ??? ??? ?console.log(this.name,this.age)
?? ??? ??? ??? ? ? ? ? ? ? ?}
?? ??? ??? ??? ? ? ? ? ?}
?? ??? ??? ?var e=new Emp("小麗",21) ?//調用構造器
?? ??? ??? ?new關鍵字具體做了什么
?? ??? ??? ? ? 1.創建了一個新對象
?? ??? ??? ? ? 2.將構造器的作用域賦給新對象
?? ??? ??? ? ? 3.用this關鍵字指向這個對象
?? ??? ??? ? ? 4.通過proto尋找父類對象
?? ??? ??? ? ? 5.返回新對象給調用者
?? ??? ?私有變量
?? ??? ??? ?在對象下變量通過this關鍵字進行執行,表示通過地址找到對象下的屬性和方法,如果要定義私有的屬性和方法,可以不通過this關鍵字定義
?? ??? ??? ?例如
?? ??? ??? ?function Emp(age){
?? ??? ??? ??? ?var name="小明" //私有變量
?? ??? ??? ??? ?this.age=age
?? ??? ??? ?}
?? ??? ??? ?var e=new Emp(22)
?? ??? ??? ?console.log(e.age)
?? ??? ??? ?console.log(e.name)
?? ??? ?this指向 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
?? ??? ??? ?this關鍵字用于對象體內,用來指向對象下的屬性和方法,方便調用
?? ??? ??? ?Global:在node環境下,this的全局作用域指向Global
?? ??? ??? ?window:在瀏覽器環境下,this的全局作用域指向window
?? ??? ??? ?例如:
?? ??? ??? ??? ?var a=11?? ??? ?//代碼題:變量提升、閉包、對象的變量傳值和this指向
?? ??? ??? ??? ?console.log(a)
?? ??? ??? ??? ?console.log(window.a)
?? ??? ??? ??? ?console.log(this.a)
?? ??? ??? ?this的指向和在哪兒定義,在哪執行都沒有關系
?? ??? ??? ?函數執行時,看函數前面是否有“.”,有的話點前面是誰就指向誰,如果沒有就指向window
?? ??? ??? ?例如:
?? ??? ??? ??? ?var name="我是window"
?? ??? ??? ??? ? ? ? ? ?var obj={
?? ??? ??? ??? ? ? ? ? ? ? ?name:"我是obj",
?? ??? ??? ??? ? ? ? ? ? ? ?info:function(){
?? ??? ??? ??? ? ? ? ? ? ? ? ? ?console.log(this.name)
?? ??? ??? ??? ? ? ? ? ? ? ?}
?? ??? ??? ??? ? ? ? ? ?}
?? ??? ??? ??? ? ? ? ? ?console.log(obj.name) //obj
?? ??? ??? ??? ? ? ? ? ?console.log(name) ?//window
?? ??? ??? ?特殊情況
?? ??? ??? ? ? 1.當this出現在匿名函數里,永遠指向的是window
?? ??? ??? ??? ?var name="我是window"
?? ??? ??? ??? ? ? ? ? ?var obj={
?? ??? ??? ??? ? ? ? ? ? ? ?name:"我是obj",
?? ??? ??? ??? ? ? ? ? ? ? ?info:function(){
?? ??? ??? ??? ? ? ? ? ? ? ? ? ?return function(){ return this.name }
?? ??? ??? ??? ? ? ? ? ? ? ?}
?? ??? ??? ??? ? ? ? ? ?}
?? ??? ??? ??? ? ? ? ? ?var n=obj.info()()
?? ??? ??? ??? ? ? ? ? ?console.log(n) ? ? //window
?? ??? ??? ? ? 2.當給一個dom元素綁定一個事件的時候,事件執行的方法體內,this指向的是當前元素
?? ??? ??? ??? ?btn.οnclick=function(){
?? ??? ??? ??? ? ? ? ? ?console.log(this) ?//指向btn按鈕
?? ??? ??? ??? ? ? ? ? ?}
?? ??? ??? ??? ? ? ? ? ?改變this指向
?? ??? ??? ??? ??? ?var name="我是window"
?? ??? ??? ??? ??? ?var obj={
?? ??? ??? ??? ??? ??? ?name:"我是obj",
?? ??? ??? ??? ??? ??? ?info:function(){ ? //匿名函數
?? ??? ??? ??? ??? ? ? ? ? ? ? ? ? ?var th=this ? //在obj環境下存一個對象
?? ??? ??? ??? ??? ? ? ? ? ? ? ?return function(){ return th.name ? //obj }
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?var n=obj.info()()
?? ??? ??? ??? ??? ?console.log(n) ? ? //obj
總結
- 上一篇: python des解密_DES-Pyt
- 下一篇: mysql使用需要钱吗_SQL Serv