Zepto源碼分析(二)奇淫技巧總結

Zepto源碼分析(一)核心代碼分析
Zepto源碼分析(二)奇淫技巧總結javascript

目錄

* 前言
    * 短路操做符
    * 參數重載(參數個數重載)
    * 參數重載(參數類型重載)
* CSS操做
    * 獲取屬性值的方法
    * 獲取屬性值的方法
* Boolean操做
    * 快速轉換成Boolean
* 日期操做
    * 快速獲取時間戳
* 數組操做
    * 數組去重
    * 數組清洗(去除null和undefined)
* 字符串操做
    * 快速轉換成字符串
    * CSS命名方式轉駝峯命名方式
    * 駝峯轉CSS命名方式
* 對象操做
    * 在閉包中修改引用會修改原對象
    * 對象中的this指向當前的上一個位置
* 判斷
    * 瀏覽器類型判斷

前言

在Zepto源碼中大量使用了三目運算符、短路操做符以及參數重載。要去完整的閱讀Zepto源碼,理解這幾種操做頗有必要。css

短路操做符

當state爲'ready'的時候,把'ok'返回給start。不然返回false給start。html

var state = 'ready'
var start = state === 'ready' && 'ok'  // 'ok'

三目運算符寫法前端

var state = 'ready'
var start = state === 'ready' ? 'ok' : false  // 'ok'

若是是if...else...結構,會這樣寫。java

var state = 'ready'
var start = ''
if (state === 'ready')  start === 'ok'  // 'ok'

參數重載(個數重載)

當第二個參數(下標是1)在arguments中,則返回'two params',不然返回'one params'。android

var paramsFun = function(a, b) {
  return (1 in arguments && 'two params') || 'one params'
}

paramsFun(2, 4)  // 'two params'
paramsFun(2)  // 'one params'

三目運算符寫法web

var paramsFun = function(a, b) {
  return 1 in arguments ? 'two params' : 'one params'
}

paramsFun(2, 4)  // 'two params'
paramsFun(2)  // 'one params'

咱們再來看看if...else的版本正則表達式

var paramsFun = function(a, b) {
  if(1 in arguments) return 'two params'
  else return 'one params'
}

paramsFun(2, 4)  // 'two params'
paramsFun(2)  // 'one params'

參數重載(類型重載)

經過1 in arguments來判斷是否存在第二個參數,以及經過判斷參數的類型執行不一樣的內容。chrome

var paramsFun = function(a, b) {
  return (1 in arguments && (typeof a ==='string' ? 'two / a is string' : 'two / a is not string')) || 'one params'
}

paramsFun(2, 4)  // "two / a is not string"
paramsFun('', 4)  // "two / a is string"

if...else寫法數組

var paramsFun = function(a, b) {
  if(1 in arguments) {
    if(typeof a ==='string') return 'two / a is string'
    return 'two / a is not string'
  }
  return 'one params'
}

paramsFun(2, 4)  // "two / a is not string"
paramsFun('', 4)  // "two / a is string"

CSS操做

Zepto中包含部分CSS黑科技。

獲取屬性值的方法

非內聯CSS咱們無法獲取到值的,這是能夠使用getComputedStyle來獲取計算後的樣式。

document.body.style.display  // ''
getComputedStyle(document.body, '').getPropertyValue('display')  // 'block'

添加Style的方法

element = document.createElement('P')
element.style.cssText += ';color:red;'
element.style.color  // 'red'

Boolean操做

快速轉換成Boolean

使用!!操做能夠快速將數據類型轉爲布爾值。

!!null  // false
Boolean(null)  // false

日期操做

快速獲取時間戳

使用+new Date()能夠快速將日期轉爲時間戳

var now = new Date();
console.log(+now)  // 1502506825489
console.log(now.getTime())  // 1502506825489

數組操做

數組去重

var uniq = function(array){ return [].filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) }
uniq([1,2,3,3])  // (3) [1, 2, 3]

數組清洗(去除null和undefined和空字符串)

function compact(array) { return [].filter.call(array, function(item){ return item != null && item != '' }) }
compact([1,2,3,3,undefined,null,''])  // [1, 2, 3, 3]

字符串操做

快速轉換成字符串

var x = 555
console.log('' + x)  // "555"

CSS命名方式轉駝峯命名方式

var camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) }
camelize('font-size')  // "fontSize"

駝峯轉CSS命名方式

function dasherize(str) {
  return str.replace(/::/g, '/')
         .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
         .replace(/([a-z\d])([A-Z])/g, '$1_$2')
         .replace(/_/g, '-')
         .toLowerCase()
}
dasherize('fontSize')  // "font-size"

對象操做

在閉包中修改引用會修改原對象

對象是引用類型,其實是修改的被引用的對象。

var x = {};

(function(y){
  y.test = 66
})(x)

console.log(x)  // {test: 66}

對象中的this指向當前的上一個位置

這個表述可能不夠嚴謹。在這裏是z屬性中的this指向了上一層的y,因此this輸出了y裏面的對象。

var x = {}
x.y = {}

x.y.z = function(){
  console.log(this)
}

x.y.z()  // {z: ƒ}

判斷

瀏覽器類型判斷

用正則表達式匹配navigator.userAgent中的信息來判斷瀏覽器類型。

var ua = navigator.userAgent  // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36"
var platform = navigator.platform
var webkit = ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/),
android = ua.match(/(Android);?[\s\/]+([\d.]+)?/),
osx = !!ua.match(/\(Macintosh\; Intel /),
ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/),
iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/),
win = /Win\d{2}|Windows/.test(platform),
wp = ua.match(/Windows Phone ([\d.]+)/),
touchpad = webos && ua.match(/TouchPad/),
kindle = ua.match(/Kindle\/([\d.]+)/),
silk = ua.match(/Silk\/([\d._]+)/),
blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/),
bb10 = ua.match(/(BB10).*Version\/([\d.]+)/),
rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/),
playbook = ua.match(/PlayBook/),
chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/),
firefox = ua.match(/Firefox\/([\d.]+)/),
firefoxos = ua.match(/\((?:Mobile|Tablet); rv:([\d.]+)\).*Firefox\/[\d.]+/),
ie = ua.match(/MSIE\s([\d.]+)/) || ua.match(/Trident\/[\d](?=[^\?]+).*rv:([0-9.].)/),
webview = !chrome && ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/),
safari = webview || ua.match(/Version\/([\d.]+)([^S](Safari)|[^M]*(Mobile)[^S]*(Safari))/)

歡迎關注前端進階指南微信公衆號:

前端進階指南

另外我也創了一個對應的QQ羣:660112451,歡迎一塊兒交流。

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息