‘==’和‘===’都是Javascript中的比較運算符,都是比較運算符兩邊是否相等。對于‘==’和‘===’的區別,大家也都知道:
‘==’僅僅是比較運算符兩邊的數值是否相等,如果數值相等則返回true;‘===’不僅會判斷運算符兩邊的數值是否相等,并且還會判斷兩邊的類型是否相等,只有數值和類型都相等才會返回true。雖然知道以上的判斷依據已經能解決絕大數此類問題,但是如果往其中深究來說,會有同學問:在比較的時候‘===’先判斷類型,如果類型不同就直接返回false,這個沒什么問題。但是如果是‘==’比較兩個不同類型的數據時,具體是怎么進行計算判斷的呢?
既然是不同類型進行比較,肯定最終參與比較的結果必須是同一個類型的,因此JS會存在一個隱式轉換的問題,并且很多JS的隱式轉換很難通過console.log()等方法直觀的觀察到,因此很多初學者會對JS的隱式轉換感到疑惑。
首先讓我們回憶一下,咱們的JS中一共有哪些數據類型?
六大數據類型
基本數據類型(簡單數據類型)
number 數值型(NaN)
string 字符串
boolean 布爾型
undefined 未定義
null 空引用
引用數據類型(復雜數據類型)
object
JS基礎中,我們學習到咱們的JS中一共有六種數據類型,分為基本數據類型(簡單數據類型)和引用數據類型(復雜數據類型),不同類型的值進行比較的時候,存在隱式轉換的問題,咱們通過‘==’來驗證一下JS隱式轉換的情況。
1.我們首先來看看下列的語句計算結果:
console.log(NaN==true);//false
console.log(NaN==false);//false
console.log(NaN==0);//false
console.log(NaN==1);//false
console.log(NaN==NaN);//false
由上面的例子可以看出,NaN屬于Number數據類型中一個特殊情況,如果‘==’兩邊同為Number數據類型的數字,很直觀的可以看出值是否相同一眼就可以看出結果,但是作為Number類型的特殊情況,NaN在進行比較的時候,也會有特殊的結果:如果 x 或 y 中有一個為 NaN,則返回 false;
2.我們繼續看看下列的語句計算結果:
console.log(null == undefined); //true(特殊情況)---------------------------------
console.log(null == ''); //false
console.log(undefined == ''); //false
在上述例子中,引出了一個null,null是一個簡單數據類型,它的意義就是一個空應用,但是你如果通過console.log(typeof null) 來打印結果的時候卻發現,結果竟然是object?此時你可能會懷疑人生,然后瘋狂的翻閱之前學習的資料,因為object明明是一個復雜數據類型,怎么會在判斷null這個簡單數據類型的類型時打印出來呢?其實,這個問題屬于一個歷史問題。咱們學習的JS在發展過程中是通過ECMAScript來確定規范的,每年都會有新的規定和規范提出,在JS的發展過程中,null一開始的作用就是用來指向一個空地址,讓開發者在創建數據的時候,先用null賦值給還未給值的對象用于標準初始化。但是其實咱們開發過程中很少用到,但是這個仍作為規范留了下來。又因為typeof是根據數據的前幾位判斷數據類型的,null相當于空指針,前幾位是地址的格式,所以判斷結果就為object。又因為undefined值是派生自null值的,因此ECMA-262規定對他們的相等測試要返回true。所以這一情況判斷的條件為:如果 x 與 y 皆為 null 或 undefined 中的一種類型,則返回 true(null == undefined // true);否則返回 false(null == 0 // false);
3.請看下列例子:
console.log(true == '123'); //false
console.log(true == '1'); //true
console.log(false == '0'); //true
console.log(true == !0); //true
console.log([] == []); //false
console.log([] == ![]); //true 比較地址 ------------------------------------------------
var a = c = [];
var b = [];
console.log(a == b); //false
console.log(a == !b); //true
console.log(a == c); //true
console.log(Boolean([]) == true); //true
console.log(Number([]) == 0); //true
console.log(Number(false) == 0); //true
其實比較的邏輯為:如果 x,y 類型不一致,且 x,y 為 String、Number、Boolean 中的某一類型,則將 x,y 使用 Number 函數轉化為 Number 類型再進行比較;
使用Number函數可以將其他的數據類型轉變為Number類型,這一同為Number類型的數據,對比起來就會變得十分簡單。值得注意的是在上述的例子中,兩個空數組進行比較,結果返回的結果仍然為false,這個是怎么回事呢?其實這個很好理解,因為數組也是對象的一種,是復雜數據類型,所以用變量儲存對象時儲存的其實是地址。對象的內容相同,但是儲存在堆區的位置不同,所以地址也是不同的,所以在判斷的時候返回的是false。
其實在JS中還有很多的隱式轉換情況,以上只是針對于‘==’的隱式轉換情況,對于這些問題,在實際開發過程中,需要作為開發者不斷的學習和積累,這也是咱們作為開發者的一個要求之一。
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
2、讀取json文件的service層實現
3、controller對應的代碼片段
4、html頁面 將jsonarray轉換成js對象
5、對js對象遍歷 $.append動態添加到對應頁面
6、效果如下圖
jquery是一個輕量級的JS框架,這點相信大部分人都聽過,而jquery之所以有這樣一個稱呼,就是因為它悄悄披了一件外衣,將自己給隱藏了起來。
/以下截取自jquery源碼片段
(function( window, undefined ) {
/* 源碼內容 */
})( window );
上面這一小段代碼來自于1.9.0當中jquery的源碼,它是一個無污染的JS插件的標準寫法,專業名詞叫閉包??梢园阉唵蔚目醋鍪且粋€函數,與普通函數不同的是,這個函數沒有名字,而且會立即執行,就像下面這樣,會直接彈出字符串。
(function( window, undefined ) {
alert("Hello World!");
})( window );
可以看出來這樣寫的直接效果,就相當于我們直接彈出一個字符串。但是不同的是,我們將里面的變量變成了局域變量,這不僅可以提高運行速度,更重要的是我們在引用jquery的JS文件時,不會因為jquery當中的變量太多,而與其它的JS框架的變量命名產生沖突。對于這一點,我們拿以下這一小段代碼來說明。
var temp = "Hello World!";
(function( window, undefined ) {
var temp = "ByeBye World!";
})( window );
alert(temp);
這段代碼的運行結果是Hello而不是ByeBye,也就是說閉包中的變量聲明沒有污染到外面的全局變量,倘若我們去掉閉包,則最終的結果會是ByeBye,就像下面這樣。
var temp = "Hello World!";
// (function( window, undefined ) {
var temp = "ByeBye World!";
// })( window );
alert(temp);
由此就可以看出來,jquery的外衣就是這一層閉包,它是很重要的一個內容,是編寫JS框架必須知道的知識,它可以幫助我們隱藏我們的臨時變量,降低污染。
剛才我們說了,jquery將自己聲明的變量全部都用外衣遮蓋起來了,而我們平時使用的Jquery和$,卻是真真實實的全局變量,這個是從何而來,謎底就在jquery的某一行代碼,一般是在文件的末尾。
window.jQuery = window.$ = jQuery;
這一句話將我們在閉包當中定義的jQuery對象導出為全局變量jQuery和$,因此我們才可以在外部直接使用jQuery和$。window是默認的JS上下文環境,因此將對象綁定到window上面,就相當于變成了傳統意義上的全局變量,就像下面這一小段代碼的效果一樣。
var temp = "Hello World!";
(function( window, undefined ) {
var temp = "ByeBye World!";
window.temp = temp;
})( window );
alert(temp);
很明顯,它的結果應該是ByeBye,而不是Hello。因為我們在閉包中導出了temp局部變量為全局變量,從而覆蓋了第一行聲明的全局變量temp。
jquery最核心的功能,就是選擇器。而選擇器簡單理解的話,其實就是在DOM文檔中,尋找一個DOM對象的工具。
首先我們進入jquery源碼中,可以很容易的找到jquery對象的聲明,看過以后會發現,原來我們的jquery對象就是init對象。
jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context, rootjQuery );
}
jQuery.fn = jQuery.prototype;
jQuery.fn.init.prototype = jQuery.fn;
這兩句話,第一句把jQuery對象的原型賦給了fn屬性,第二句把jQuery對象的原型又賦給了init對象的原型。也就是說,init對象和jQuery具有相同的原型,因此我們在上面返回的init對象,就與jQuery對象有一樣的屬性和方法。
很多時候,我們在jQuery和DOM對象之間切換時需要用到[0]這個屬性。從截圖也可以看出,jQuery對象其實主要就是把原生的DOM對象存在了[0]的位置,并給它加了一系列簡便的方法。這個索引0的屬性我們可以從一小段代碼簡單的看一下它的由來,下面是init方法中的一小段對DOMElement對象作為選擇器的源碼。
// Handle $(DOMElement)
if ( selector.nodeType ) {
/* 可以看到,這里將DOM對象賦給了jQuery對象的[0]這個位置 */
this.context = this[0] = selector;
this.length = 1;
return this;
}
這一小段代碼可以在jquery源碼中找到,它是處理傳入的選擇參數是一個DOM對象的情況。可以看到,里面很明顯的將jQuery對象索引0的位置以及context屬性,都賦予了DOM對象。代碼不僅說明了這一點,也同時說明了,我們使用$(DOMElement)可以將一個DOM對象轉換為jQuery對象,從而通過轉換獲得jQuery對象的簡便方法。
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
目前做的項目是ionic3和angular4.0的結合,所以用到了很多關于ionic3中封裝好的標簽,例如具有輪播效果的ion-slides和ion-slide等。那么這次就要總結一下另外一個標簽ion-segment的用法了。
Segment 在頭部使用
Segment 在內容里面使用
Segment 在表單里面使用
ion-segment這個標簽以前用的很少,幾乎沒有用過。它主要是一組按鈕,有時稱為分段控件,之前都是用button按鈕,現在知道了,開始用ion-segment,因為它有自帶的樣式,這樣就可節省很多時間,同時呢允許用戶與許多控件的緊湊組進行交互。 分段提供與標簽相似的功能,選擇一個將取消選擇所有其他選項。 當您希望讓用戶在應用程序的不同頁面之間來回移動時,應使用選項卡欄而不是分段控件。 您可以使用Angular的ngModel或FormBuilder API。
下面來看一段代碼:
<ion-header> <ion-toolbar> <ion-segment [(ngModel)]="icons" color="secondary"> <ion-segment-button value="camera"> <ion-icon name="camera">帶iocn</ion-icon> </ion-segment-button> <ion-segment-button value="bookmark"> 頭部使用Segment <ion-icon name="bookmark"></ion-icon> </ion-segment-button> </ion-segment> </ion-toolbar> </ion-header>
<ion-segment [(ngModel)]="relationship" color="primary" (ionChange)="segmentChanged($event)"> <ion-segment-button value="friends"> Segment 在內容里面使用 </ion-segment-button> <ion-segment-button value="enemies"> 可以綁定一個事件(ionChange) </ion-segment-button> </ion-segment>
<form [formGroup]="myForm"> <ion-segment formControlName="mapStyle" color="danger"> <ion-segment-button value="standard"> Standard </ion-segment-button> <ion-segment-button value="hybrid"> 表單內使用 </ion-segment-button> <ion-segment-button value="sat"> Satellite </ion-segment-button> </ion-segment> </form>
Segment 配合ngSwitch使用
<ion-segment [(ngModel)]="change"> <ion-segment-button value="apple"> 蘋果 </ion-segment-button> <ion-segment-button value="pie"> 梨 </ion-segment-button> </ion-segment> <div [ngSwitch]="change"> <div *ngSwitchCase="'apple'">
蘋果顯示,如果要默認顯示一個就把默認的那個設置一個初始值比如要默認顯示蘋果就把蘋果的value值設置成change也就是說,在定義change變量的時候,需要把哪個設置為默認顯示就把哪個的value值賦值給change作為初始值 public change=”pie”;
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
在我們的頁面布局的時候,經常會有這樣的需求,超過指定行文本的時候會進行(省略號...)的處理,那么我們改怎么設置css呢?如下:
設置盒子的css為:
但是這樣只能顯示一行而不能實現指定行,所以還要其他的方法來實現指定行處理的。
WebKit瀏覽器或移動端的頁面(大部分移動端都是webkit)
css 代碼:
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
1:安裝
2: 在main.js 主入口js里面引用store.js
3:在store.js里引用Vuex
4:在vue組件中使用
使用$store.commit(‘jia’)區觸發mutations下面的加減方法
5:state訪問狀態對象
使用computed計算
npm install vuex --save
import Vue from 'vue' import App from './App' import router from './router' import store from './vuex/store' //引用store.js Vue.config.productionTip = false //阻止在啟動時生成生產提示 //vue實例 new Vue({
el: '#app',
router,
store, //把store掛在到vue的實例下面 template: '<App/>',
components: { App }
})
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) //注冊Vuex // 定義常量 如果訪問他的話,就叫訪問狀態對象 const state = {
count: 1 } // mutations用來改變store狀態, 如果訪問他的話,就叫訪問觸發狀態 const mutations = { //這里面的方法是用 this.$store.commit('jia') 來觸發 jia(state){
state.count ++
},
jian(state){
state.count --
},
} //暴露到外面,讓其他地方的引用 export default new Vuex.Store({
state,
mutations
})
<template> <p class="hello"> <h1>Hello Vuex</h1> <h5>{{$store.state.count}}</h5> <p> <button @click="$store.commit('jia')">+</button> <button @click="$store.commit('jian')">-</button> </p> </p> </template> <!-- 加上scoped是css只在這個組件里面生效,為了不影響全局樣式 --> <style scoped> h5{ font-size: 20px; color: red; } </style>
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務 <template> <p class="hello"> <h1>Hello Vuex</h1> <h5>{{count}}</h5> <p> <button @click="$store.commit('jia')">+</button> <button @click="$store.commit('jian')">-</button> </p> </p> </template> <script> import {mapState} from 'vuex' export default{
name:'hello', //寫上name的作用是,如果你頁面報錯了,他會提示你是那個頁面報的錯,很實用 // 方法一 // computed: { // count(){ // return this.$store.state.count + 6 // } // } // 方法二 需要引入外部 mapState computed:mapState({
count:state => state.count + 10 }) // ECMA5用法 // computed:mapState({ // count:function(state){ // return state.count // } // }) //方法三 // computed: mapState([ // 'count' // ]) } </script>
傳統方法的缺點:
傳統的web交互是用戶觸發一個http請求服務器,然后服務器收到之后,在做出響應到用戶,并且返回一個新的頁面,,每當服務器處理客戶端提交的請求時,客戶都只能空閑等待,并且哪怕只是一次很小的交互、只需從服務器端得到很簡單的一個數據,都要返回一個完整的HTML頁,而用戶每次都要浪費時間和帶寬去重新讀取整個頁面。這個做法浪費了許多帶寬,由于每次應用的交互都需要向服務器發送請求,應用的響應時間就依賴于服務器的響應時間。這導致了用戶界面的響應比本地應用慢得多。
什么是ajax?
ajax的出現,剛好解決了傳統方法的缺陷。AJAX 是一種用于創建快速動態網頁的技術。通過在后臺與服務器進行少量數據交換,AJAX 可以使網頁實現異步更新。這意味著可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。
XMLHttpRequest 對象
XMLHttpRequest對象是ajax的基礎,XMLHttpRequest 用于在后臺與服務器交換數據。這意味著可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。目前所有瀏覽器都支持XMLHttpRequest。
方法
|
描述
|
abort() |
停止當前請求 |
getAllResponseHeaders() |
把HTTP請求的所有響應首部作為鍵/值對返回 |
getResponseHeader("header") |
返回指定首部的串值 |
open("method","URL",[asyncFlag],["userName"],["password"]) |
建立對服務器的調用。method參數可以是GET、POST或PUT。url參數可以是相對URL或絕對URL。這個方法還包括3個可選的參數,是否異步,用戶名,密碼 |
send(content) |
向服務器發送請求 |
setRequestHeader("header", "value") |
把指定首部設置為所提供的值。在設置任何首部之前必須先調用open()。設置header并和請求一起發送 ('post'方法一定要 ) |
1.創建XMLHTTPRequest對象
2.使用open方法設置和服務器的交互信息
3.設置發送的數據,開始和服務器端交互
4.注冊事件
5.更新界面
下面給大家列出get請求和post請求的例子 :
get請求:
//步驟一:創建異步對象
var ajax = new XMLHttpRequest();
//步驟二:設置請求的url參數,參數一是請求的類型,參數二是請求的url,可以帶參數,動態的傳遞參數starName到服務端
ajax.open('get','getStar.php?starName='+name);
//步驟三:發送請求
ajax.send();
//步驟四:注冊事件 onreadystatechange 狀態改變就會調用
ajax.onreadystatechange = function () {
if (ajax.readyState==4 &&ajax.status==200) {
//步驟五 如果能夠進到這個判斷 說明 數據 完美的回來了,并且請求的頁面是存在的
console.log(xml.responseText);//輸入相應的內容
}
}
post請求:
//創建異步對象
var xhr = new XMLHttpRequest();
//設置請求的類型及url
//post請求一定要添加請求頭才行不然會報錯
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.open('post', '02.post.php' );
//發送請求
xhr.send('name=fox&age=18');
xhr.onreadystatechange = function () {
// 這步為判斷服務器是否正確響應
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);
}
};
為了方便使用,我們可以把他封裝進方法里面,要用的時候,直接調用就好了。
function ajax_method(url,data,method,success) {
// 異步對象
var ajax = new XMLHttpRequest();
// get 跟post 需要分別寫不同的代碼
if (method=='get') {
// get請求
if (data) {
// 如果有值
url+='?';
url+=data;
}else{
}
// 設置 方法 以及 url
ajax.open(method,url);
// send即可
ajax.send();
}else{
// post請求
// post請求 url 是不需要改變
ajax.open(method,url);
// 需要設置請求報文
ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded");
// 判斷data send發送數據
if (data) {
// 如果有值 從send發送
ajax.send(data);
}else{
// 木有值 直接發送即可
ajax.send();
}
}
// 注冊事件
ajax.onreadystatechange = function () {
// 在事件中 獲取數據 并修改界面顯示
if (ajax.readyState==4&&ajax.status==200) {
// console.log(ajax.responseText);
// 將 數據 讓 外面可以使用
// return ajax.responseText;
// 當 onreadystatechange 調用時 說明 數據回來了
// ajax.responseText;
// 如果說 外面可以傳入一個 function 作為參數 success
success(ajax.responseText);
}
}
}
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
1:mutations觸發狀態 (同步狀態)
2:getters計算屬性
getter不能使用箭頭函數,會改變this的指向
在store.js添加getters
//count的參數就是上面定義的state對象
3:actions (異步狀態)
在store.js添加actions
在組件中使用
4:modules 模塊
適用于非常大的項目,且狀態很多的情況下使用,便于管理
修改store.js
<template> <p class="hello"> <h1>Hello Vuex</h1> <h5>{{count}}</h5> <p> <button @click="jia">+</button> <button @click="jian">-</button> </p> </p> </template> <script> import {mapState,mapMutations} from 'vuex' export default{
name:'hello', //寫上name的作用是,如果你頁面報錯了,他會提示你是那個頁面報的錯,很實用 //方法三 computed: mapState([ 'count' ]),
methods:{
...mapMutations([ 'jia', 'jian' ])
}
} </script>
// 計算 const getters = {
count(state){ return state.count + 66 }
} export default new Vuex.Store({
state,
mutations,
getters
})
//getters中定義的方法名稱和組件中使用的時候一定是一致的,定義的是count方法,使用的時候也用count,保持一致。
組件中使用
<script> import {mapState,mapMutations,mapGetters} from 'vuex' export default{
name:'hello',
computed: {
...mapState([ 'count' ]),
...mapGetters([ 'count' ])
},
methods:{
...mapMutations([ 'jia', 'jian' ])
}
} </script>
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) // 定義常量 const state = { count: 1 } // mutations用來改變store狀態 同步狀態 const mutations = {
jia(state){
state.count ++
},
jian(state){
state.count --
},
} // 計算屬性 const getters = {
count(state){ return state.count + 66 }
} // 異步狀態 const actions = {
jiaplus(context){
context.commit('jia') //調用mutations下面的方法
setTimeout(()=>{
context.commit('jian')
},2000) alert('我先被執行了,然后兩秒后調用jian的方法') }, jianplus(context){ context.commit('jian') }
} export default new Vuex.Store({
state,
mutations,
getters,
actions
})
<template> <p class="hello"> <h1>Hello Vuex</h1> <h5>{{count}}</h5> <p> <button @click="jia">+</button> <button @click="jian">-</button> </p> <p> <button @click="jiaplus">+plus</button> <button @click="jianplus">-plus</button> </p> </p> </template> <script> import {mapState,mapMutations,mapGetters,mapActions} from 'vuex' export default{
name:'hello',
computed: {
...mapState([ 'count' ]),
...mapGetters([ 'count' ])
},
methods:{ // 這里是數組的方式觸發方法 ...mapMutations([ 'jia', 'jian' ]), // 換一中方式觸發方法 用對象的方式 ...mapActions({
jiaplus: 'jiaplus',
jianplus: 'jianplus' })
}
} </script> <style scoped> h5{ font-size: 20px; color: red; } </style>
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務 import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const state = { count: 1 } const mutations = {
jia(state){
state.count ++
},
jian(state){
state.count --
},
} const getters = {
count(state){ return state.count + 66 }
} const actions = {
jiaplus(context){
context.commit('jia') //調用mutations下面的方法
setTimeout(()=>{
context.commit('jian')
},2000) alert('我先被執行了,然后兩秒后調用jian的方法') }, jianplus(context){ context.commit('jian') }
}
//module使用模塊組的方式 moduleA const moduleA = { state, mutations, getters, actions }
// 模塊B moduleB const moduleB = { state: { count:108
}
} export default new Vuex.Store({
modules: {
a: moduleA,
b: moduleB,
}
})
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
window全局作用域->頁面關掉才銷毀
1)作用域的銷毀
2)作用域的不立即銷毀
fn()(20);//->在執行fn的時候一切都從新開始了,和上面的步驟是一樣的->輸出30
3)作用域的不銷毀:形成一個私有作用域,里面的內容被外面占用了
2)在函數執行的時候,里面的一個小函數的地址賦值給了我們的外面元素的點擊事件,那么當前小函數也相當于被外面占用了,大函數執行形成的私有的作用域也不銷毀了
3)在使用setTimeout實現輪詢動畫的時候,我們如果move需要傳遞參數值,那么像下面這樣的寫法會行成很多的不銷毀的作用域,非常的耗性能
//window.setTimeout(move,10); ->第二次執行move的時候我們沒有給它傳值(這樣寫不行)
//解決辦法:
[火狐和IE]
var obj={};
函數執行會形成私有的作用域
一般情況下,函數執行形成一個私有的作用域,當執行完成后就銷毀了->節省內存空間
function fn(){
var i=10;
return function(n){
console.log(n+i++);
}
}
fn()(15);//->先執行fn,有一個私有的變量i=10,返回一個堆內存地址 xxxfff111,我們發現這個地址還用到了一次,那么當前的這個fn形成私有作用域(A)就不能立即銷毀了,xxxfff111(15)->輸出25,A中的i變為11;當xxxfff111執行完了,發現這個地址沒用了,瀏覽器就把A、xxxfff111都釋放了
function fn(){
var i=10;
return function(n){
console.log(n+i++);
}
}
var f=fn();//->fn執行形成一個私有的作用域A,A中有一個私有的變量i=10,A中返回一個地址xxxfff11,被外面的f占用了,那么當前的A就不能銷毀了
f(15);//->輸出25,讓A中的i=11
f(20);//->輸出31,讓A中的i=12
…
當我們知道f用完的時候,為了優化性能,我們讓f=null,這樣的話A中的xxxfff111沒人占用了,瀏覽器會把A和xxxfff111都釋放了
幾種不銷毀常用到的形式:
1)函數執行,返回一個引用數據類型的值,并且在函數的外面被別人接收了,那么當前函數形成的私有作用域就不在銷毀了–>例如上面的案例
//每一次循環都執行自執行函數形成一個私有的作用域(循環三次就有三個作用域,每一個作用域中都有一個i,第一個存儲的是0,第二個存數的是1..),在每一個私有的作用域中都把里面的函數綁定給了外面元素的點擊事件,這樣的話每一次形成的作用域都不銷毀了(三個不銷毀的作用域)
var oLis=document.getElementsByTagName(“li”);
for(var i=0;i<oLis.length;i++){
~function(i){
oLis[i].onclick=function(){
tabChange(i);
}
}(i);
}
function move(tar){
<js code>
window.setTimeout(function(){
move(tar);
},10);//->這樣寫實現了,但是每一次執行定時器都會形成一個私有的所用域(匿名函數形成的)A,在A中使用了上級作用域中的tar的值,而且執行了move又形成了一個小的作用域(而在小的作用域中會使用tar的值),這樣每一次定時器形成的A都不能銷毀了
}
move(100);//->第一次這樣執行傳遞100
function move(tar){
~function _move(){
<js code>
window.setTimeout(_move,10);
}();
}
move(100);//->第一次這樣執行傳遞100
JS中內存空間釋放的問題(堆內存、棧內存)
[谷歌瀏覽器]
我們開辟一個內存,可能或有一些其他的變量等占用了這個內存,谷歌瀏覽器都會間隔一段時間看這個內存還有沒有被占用,如果發現有沒有被占用的內存了,就自己幫我們回收了(內存釋放)
我們開個內存,當我們引用了它,就在內存中記錄一個數,增加一個引用瀏覽器就把這個數+1,減少一個引用,瀏覽器就把這個數-1…當減到零的時候瀏覽器就把這個內存釋放了;但是有些情況下(尤其是IE)記著記著就弄亂了,內存就不能釋放了–>瀏覽器的內存泄露
我們養成一個好的習慣,當我們obj這個對象使用完成了,我們手動的obj=null (null空對象指針),瀏覽器會自己把剛才的堆內存釋放掉
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
頭:header
內容:content/container
尾:footer
導航:nav
側邊欄:sidebar
欄目:column
頁面外圍控制整體布局寬度:wrapper
左中右:left center right
登錄條:loginbar
標志:logo
版心:banner
頁面主體:main
熱點:hot
新聞:news
下載:download
子導航:subnav
菜單:menu
子菜單:submenu
搜索:search
友情鏈接:friendlink
頁腳:footer
版權:copyright
滾動:scroll
標簽頁:tab
文章列表:list
提示信息:msg
小技巧:tips
欄目標題:title
加入:joinUS
指南:guide
服務:service
注冊:regsiter
狀態:status
投票:vote
合作伙伴:partner
藍藍設計的小編 http://www.syprn.cn