Javascript學習日誌

數據類型

Array方法

splice(索引, 刪除個數, [newObject])  [newObject]:可選參數;

arr.splice(0, 1) 
arr.splice(0, 1, 'a') 

sort()排序; 

var arr = ['a', 'd', 'c', 'b']
arr.sort() 

 indexOf(item) 索引,-1爲不存在;

var object = arr.indexOf('1')

slice(索引, 取出個數); 

var arr1 = arr.slice(0, 3);

concat(arr) 合併數組;

var arr2 = arr.concat(arr1)

array轉string,中間‘,’隔開,等同於toString()

let str = arr.join(',') 
let str1 = arr.toString()

push(object, ..., object) 添加一個或多個對象;

var arr = ['a']
arr.push('b') 
arr.push('c', 'd') 

從數組頭添加對象;

var arr = []
arr.unshift('a')
arr.unshift('b', 'c')

typeof arr1 === 'object' 數組的type爲object;

var arr = arr1.concat(arr2) //生成新的內存
arr1.push.apply(arr1, arr2) 
Array.prototype.push.apply(arr1, arr2) //合併到arr1中

String方法

數字和字符串相互轉換;

var integer = parseInt('666') /* 轉換函數 */
var integer1 = Number('888')  /* 強制類型轉換 */

var str = integer.toString()  /* 轉換函數 */
var str1 = String(integer1)   /* 強制類型轉換 */

replace("current", "new")  第一個被替; 

str.replace("current", "new")

replace(/current/g, "new") 全部替換;

str.replace(/current/g, "new") 

split(" ")  根據空格生成array;

str.split(" ") 

substr(索引, 個數)  個數可選,不填則表示索引處全取;

str.substr(0, 2) 

toLowerCase()  toUpperCase()  大小寫;

str.toLowerCase()
str.toUpperCase()

slice(start, end) 取出start~end的字符,end可選;

str.slice(2, 5)

concat(str) 拼接字符串,等同於‘+’;

str.concat('a', 'b', 'c')

let str1 = str + 'a' + 'b' + 'c'

indexOf('subStr') 索引,-1爲不存在

str.indexOf('abc')

Object方法

Object.assign(object1, object2) 合併對象(object2合併到object1)

鍵值對第一層爲深拷貝,第二層和以上爲淺拷貝(又稱一級拷貝)

Object.assign(object1, object2) //object1內存地址不變
var newObject = Object.assign({}, {key: 'value'}, {key2: 'value2'}) //生成新的對象
delete newObject.key  //刪除key-value
delete newObject['key2'] //刪除key2-value2

var keys = Object.keys(object1) //獲取object1的keys
var values = Object.values(object1) //獲取object1的values

var keys2 = Object.getOwnPropertyNames(object2) //獲取object2的keys

變量類型-typeof

console.log(typeof firstObject)    //'undefined'
console.log(typeof(false))         //'boolean'
console.log(typeof 'helloworld')   //'string'
console.log(typeof 27)             //'number'
console.log(typeof NaN)            //'number'
console.log(typeof null)           //'object'    

var str = new String()
console.log(typeof(str))           //'object'

var  fn = function(){}
console.log(typeof(fn))            //'function'

console.log(typeof(class c{}))     //'function'

變量爲空判斷


/* 等同於 if(variable) console.log('variable爲空') */
if (variable === null || variable === undefined || variable === '' || variable === 0) {
   console.log('variable爲空')
}

/* 等同於 variable === undefined */
typeof (variable) === 'undefined'

var str = ''
str.length === 0

var arr = []
arr.length === 0

var data = {}
var keys = Object.keys(data)
keys.lenght === 0

JSON方法 

var myJson = JSON.stringify(object)  //object轉jsonString
var object = JSON.parse(myJson)  //jsonString轉object
/* 兩方法一起用可以實現深拷貝 */

Date方法

new Date('2019/04/23').getTime()   =>  Date.parse('2019/04/23')

Date.now()  =>  new Date().getTime()  時間戳

/* dateString 轉 時間戳 通用格式'xxxx/xx/xx xx:xx:xx' */
var dateStr = '2019-05-19'
dateStr = dateStr.replace(/-/g, '/')
var date = new Date(dateStr)
let time = date.getTime()
/* 時間戳 轉 dateString 'xxxx-xx-xx xx:xx:xx' */
function formatDate(date) { 
  var year = date.getFullYear()
  var month = date.getMonth() + 1
  var day = date.getDate()
  var hour = date.getHours()
  var minute = date.getMinutes()
  var second = date.getSeconds()
  return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second
} 

var date = new Date(1230999938); 
var dateString = formatDate(date);

定時器

setTimeout

var timeout = setTimeout(() => {
    //延時調用
}, 1000);

//取消延時器
clearTimeout(timeout);

setInterval

var interval = setInterval(() => {
  //循環調用
}, 1000);

//取消定時器
clearInterval(interval);

Dom方法

document.documentElement.scrollTop = 270  //跳至到270的位置
document.getElementById('el').scrollIntoView()  //跳至指定元素位置
var element = document.getElementById('el')
element.style.color = '#50d6c2' //元素屬性賦值

屬性初始化

/* response沒有聲明,報undefined */
this.response.error = (err) => {}

/* 修正後的代碼示例 */
this.response = {}
this.response.error = (err) => {}

函數、閉包

var infoFunc = deviceInfo => { } /*類似 function(deviceInfo) { } */
var func = () => {  }  /*類似 function() { } */
var verfunc = (verA, verB) => { }  /*類似 function(verA, verB) { } */

let _this = this /* 多層嵌套可以引用'_this',單個閉包'=>{}'直接用'this'就行 */

/* 用法跟ios的block相似,可作爲傳參並接受回調,也可以只作爲一個閉包(方法),實現方法的調用 */

HTTP-AXIOS 

axios是通過promise實現對ajax技術的一種封裝

  • 支持瀏覽器和node.js
  • 支持promise
  • 能攔截請求和響應
  • 能轉換請求和響應數據
  • 能取消請求
  • 自動轉換JSON數據
  • 瀏覽器端支持防止CSRF(跨站請求僞造)
/* axios的兩種調用方式 */
axios({
    method: 'post',
    url: '/user/login',
    data: { username: '123456', password: 'ABC23456' }
}).then(function (res) {
    console.log(res);
}).catch(function (err) {
    console.log(err);
});

axios.get('user/userinfo').then(res => {
    console.log(res);
}).catch(err => {
    console.log(err);
});

公共庫的引用

/*  stream.js */
var Stream = {
   gateWayAjax: function(options) {
     console.log('gateWayAjax')
   }
}
export default Stream

/*  util.js */
export let compareVersion = (verA, verB)=> { }
/*等同 export function compareVersion(verA, verB) { }*/
export const debug = true

/* vue引用 */
import UtilStream from 'Utils/stream' // UtilStream == export default Stream
improt { debug, compareVersion } from 'Utils/util' // const命名必須一致

export defealt {
  created() {
    UtilStream.gateWayAjax({ })
    compareVersion(appVersion, '2.0.2')
    console.log('It is debug:' + debug)
  }
}

/* Api.js */
var Api = {
  interface: {
    $reqData: this.$reqData
  }
  $reqData() {
    Axios.post()
  }
}
export const api = Object.assign(Api.interface)

/* Sql.js  sql與api結構相似{key:value} */
$queryData() {
  console.log('queryData')
}
$insertData() {
  console.log('insertData')
}
export const sql = { $queryData, $insertData }

/* vue引用 */
import { api } from 'utils/Api'
import { sql } from 'utils/Sql'

export default {
  methods: {
    ...api,
    ...sql,
    reqData() {
      this.$reqData()
      /* methods引入...api後,可以直接this.調用api中的方法 */
    },
    queryData() {
      this.$insertData()
      this.$queryData()
      /* methods引入...sql後,可以直接this.調用sql中的方法 */
    }
  }
}

構造函數、原型對象

在 JavaScript 中,用 new 關鍵字來調用的函數,稱爲構造函數。

function construct() {
   var data = {}
   function method(params) {
      // do something
   }
}

var constructObj = new construct()

用prototype可以實現構造函數的擴展和繼承 

/* 通過prototype實現擴展 */
function Construct() {
   var data = {}
   function method(params) {
      // do something
   }
}

// 方法擴展
Construct.prototye.setvalue = (value) => {
   // do something
}

var constructObj = new Construct()
constructObj.setValue('賦值')
/* 通過prototype實現繼承 */
function Construct() {
   var data = {}
   function method(params) {
      // do something
   }
}

function SuperClass() {
   var params = {}
   function setValue(value) {
      // do something
   }
}

// 繼承
Construct.prototye = new SuperClass()

var constructObj = new Construct()
constructObj.method('參數')
constructObj.setValue('賦值')

構造函數和原型對象的關關聯如下圖:

  • 實例的constructor指向構造函數;
  • 函數對象纔有prototype屬性;
  • 原型對象是構造函數的一個實例;

線程

JavaScript引擎

JavaScript引擎是基於事件驅動單線程執行的,JavaScript引擎一直等待着任務隊列中任務的到來,然後加以處理,瀏覽器無論什麼時候都只有一個JavaScript線程在運行JavaScript程序。

GUI渲染線程

GUI渲染線程負責渲染瀏覽器界面,當界面需要重繪或由於某種操作引發迴流時,該線程就會執行,但需要注意,GUI渲染線程與JavaScript引擎是互斥的,當JavaScript引擎執行時GUI線程會被掛起,GUI更新會被保存在一個隊列中等到JavaScript引擎空閒時立即被執行。

事件觸發線程

當一個事件被觸發時該線程會把事件添加到待處理隊列的隊尾,等待JavaScript引擎的處理;這些事件可來自JavaScript引擎當前執行的代碼塊,如setTimeout、也可來自瀏覽器內核的其他線層,如鼠標點擊、Ajax異步請求等,但由於JavaScript的單線程關係,所有這些事件都得排隊等待JavaScript引擎處理。

同步與異步

JavaScript是單線程執行機制,但也可以實現同異步操作,同步任務直接在當前線程執行,異步任務則先進入任務隊列,當事件觸發線程檢測到JavaScript引擎空閒時,會讀取任務隊列,並執行對應的任務(當線程中沒有執行任何同步代碼的情況下才會執行異步代碼)。

異步的回調處理

Promise

Promise簡單來說就是一個容器,從它可以獲取異步操作的消息。

/* 正常執行後的回調 */
let p = new Promise((resolve, reject) => {
    resolve('resolve')
});

p.then(result => {
    console.log(result);
});

Promise同時執行resolve()和reject()時,只能觸發其中一個監聽,也就是最終只會回調 ‘正常狀態’ 或者 ‘異常狀態’

/* 正常及異常的監聽回調實現 */
let p = new Promise((resolve,reject) => {
    let result = (response.ret === 0)
    if(result) {
        resolve(response)
    } else {
        reject('error')
    }
    /* reject調用無效
     * resolve(response)
     * reject('error')
     */
});

/* 兩種書寫方式 */
p.then(res => {
    console.log('response',res)
}, err => {
    console.log('error',err)
})

p.then(res => {
    console.log('response',res)
}).catch(err => {
    console.log('error',err)
})

 async、wait

async用於申明一個function是異步的,而await可以認爲是async wait的簡寫,等待一個異步方法執行完成。

async function asyncMethod() {
   return HTTPReq()
}

/* async函數返回的是Promise對象 */
let p = asyncMethod()
p.then(res => { })

 使用await必須在該函數中添加async聲明,async await把異步轉成同步,直接返回結果。

/* 直接返回結果 */
async function asyncMethod() {
   let response = await HTTPReq()
   return response
}

asyncMethod().then(res => {
   this.console.log(res)
})

var、let和const的區別

作用域:又分爲全局作用域、函數作用域和塊作用域 。

/* 全局作用域 */
var array = ['a', 'b', 'c']  //全局變量

/* 函數作用域 */
function foo () {  
   var string = 'string'  //局部變量

   /* 塊作用域 */
   if(string) {
      console.log(`foo:${string}`)  //foot:string
   }
}
foo()

/* 函數外無法直接訪問局部變量 */
console.log(`string:${string}`)  //Uncaught ReferenceError: string is not defined

var、let和const的主要區別有以下三點:

  1. var 聲明的變量屬於函數作用域,let 和 const 聲明的變量屬於塊級作用域;
  2. var 存在變量提升現象,而 let 和 const 沒有此類現象;
  3. var 變量可以重複聲明,而在同一個塊級作用域,let 變量不能重新聲明,const 變量不能修改。

var

如果使用關鍵字 var 聲明一個變量,那麼這個變量就屬於當前的函數作用域,如果聲明是發生在任何函數外的頂層聲明,那麼這個變量就屬於全局作用域。

var a = 1  //此處聲明的變量a爲全局變量
function test(){
   var a = 2 //此處聲明的變量a爲函數foo的局部變量
   console.log(a) //2
}
test()
console.log(a) //1

如果在聲明變量時,省略 var 的話,該變量就會變成全局變量,如全局作用域中存在該變量,就會更新其值。

var a = 1 //此處聲明的變量a爲全局變量
function test(){
   a = 2  //此處的變量a也是全局變量
   console.log(a)  //2
}
test();
console.log(a)  //2
console.log(a)  //undefined
var a = 1

var a
console.log(a)  //undefined
a = 1

console.log(b)  //假設b未聲明過,Uncaught ReferenceError: b is not defined

let

let 聲明的變量,具有如下幾個特點:

  1. let 聲明的變量具有塊作用域的特徵。
  2. 在同一個塊級作用域,不能重複聲明變量。
  3. let 聲明的變量不存在變量提升,換一種說法,就是 let 聲明存在暫時性死區(TDZ)。
let a = 1
console.log(a)  //1
console.log(b)  //Uncaught ReferenceError: b is not defined
let b = 2

function test(){
    let a = 1
    let a = 2  //Uncaught SyntaxError: Identifier 'a' has already been declared
}

以下是一個經典的關於 var 和 let 的一個例子: 

for (var i = 1; i <= 5; i++) {
   setTimeout(function(){
      console.log(i)
   }, 100)
};
//依次打印:6 6 6 6 6 (var)

for (let i = 1; i <= 5; i++) {
   setTimeout(function(){
      console.log(i)
   }, 100)
};
//依次打印:1 2 3 4 5 (用let聲明)

for (var i = 1; i <= 5; i++) {
   function foo(j) {
      setTimeout(function(){
         console.log(j)
      }, 100)
   }
   foo(i)
};
//依次打印:1 2 3 4 5(用一個閉包把i的作用域包起來)

const 

const 聲明方式,除了具有 let 的上述特點外,其還具備一個特點,即 const 定義的變量,一旦定義後,就不能修改,即 const 聲明的爲常量。

const a = 1
console.log(a)  //1
a = 2
console.log(a)  //Uncaught TypeError: Assignment to constant variable.

但並不是說 const 聲明的變量其內部內容不可變 。

const obj = {a: 1, b: 2} 
console.log(obj.a)  //1
obj.a = 3
console.log(obj.a)  //3

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章