Websocket同http同樣都是是基於tcp的,可靠性的雙向通訊協議,是創建在tcp之上的,而且是持久化的協議。css
相同點html
不一樣點node
不一樣點git
基本類型github
複雜類型web
值類型:面試
引用類型:ajax
特殊引用類型:function正則表達式
注意:typeof沒法詳細區分引用類型的類型,除了function. 只能準確區分值類型的類型
好比:算法
typeof {} //object typeof [] //object typeof null //object typeof console.log // function
function是一個比較特殊的類型,因此typeof可以區分
儘量使用 === 緣由以下
== 的使用狀況,可參考
var obj = {}; if( obj.a == null ){ //這裏相對於:obj.a === null || obj.a === undefined 的簡寫形式,JQ源碼的推薦寫法 }
function fn( a, b){ if( b == null ){ //這裏至關於 b===null || b === undefined 的簡寫 } }
從純JS的角度看,JSON就是對象,而且只有兩個API
JSON.stringify({a:10,b:30}) //將對象轉爲字符串 JSON.parse('{"a":10,"b":30}') //將JSON格式的字符串轉爲 對象
var a = 100; console.log( !!a ); //true
可參看這篇博文:https://github.com/youngwind/...
//該方法最簡單,效果通常,每一個元素仍然有很大機率在它原來的位置附近出現 arr.sort(function () { return Math.random() - 0.5; });
//Fisher–Yates shuffle費雪耶茲隨機置亂算法) !!!推薦
//算法思想:從0~i(i的變化爲 n-1到0遞減)中隨機取得一個下標,和最後一個元素(i)交換。 var arr = [5,8,59,56]; function shuffle(arr) { var i = arr.length, t, j; while (i) { j = Math.floor(Math.random() * i--); t= arr[i]; arr[i] = arr[j]; arr[j]= t; } } shuffle(arr) console.log(arr);//[56, 8, 5, 59]
原型鏈是針對構造函數的,好比我建立了一個函數並經過變量new了一個函數,那這個函數就會繼承建立處理函數的屬性,若是訪問這個函數的屬性時,並無在new處理的變量中寫該屬性,那麼就會往上,根據protype逐級向上查找,這個查找的過程就叫原型鏈。
因爲它的隱式原型等於它的顯式原型,因此也會去 prototype 中去找。
function Foo(name,age){ this.name = name; this.age = age; } var foo = new Foo('h1',25); var foo2 = new Foo('h1',250); console.log(foo,foo2); //循環對象自身的屬性 var item; for( item in foo) { //只遍歷對象自身的屬性,過濾掉該對象的顯式原型 if(foo.hasOwnProperty(item)) { console.log(item) } }
var arr = [1,2,3]; console.log(Array.isArray(arr)); //true //instanceof運算符用於測試構造函數的prototype屬性是否出如今對象的原型鏈中的任何位置 console.log( arr instanceof Array) //true
function Elem(id){ this.dom = document.getElementById(id); } Elem.prototype.html = function(val){ var dom = this.dom; if(val){ dom.innerHTML = val; return this; //用來鏈式調用 }else{ return dom.innerHTML; } } Elem.prototype.on = function(type ,fn){ var dom = this.dom; dom.addEventListener( type , fn); } var h1 = new Elem('h1'); h1.html("你被修改了").on('click', function(){ console.log(this) })
`做用域是針對變量的,好比我建立了一個函數,這個函數中包含了另一個函數。那麼該變量中就有3個做用域
全局做用域》函數做用域》內層函數的做用域
做用域的特色就是,先在本身的變量範圍中查找,若是找不到,就會沿着做用域往上找。
`
注意:this要在執行時才能確認值,定義時沒法確認
function f1(name,age){ console.log(name,age) console.log(this); //this爲x對象 } f1.apply({x:'我是this'}, ["seek",20]); f1.call({x:'我是this'}, "seek",20); //使用bind改變this時,需用函數表達式 var f1 = function (name,age){ console.log(name,age) console.log(this); //this爲x對象 }.bind('我是被綁定的this') f1("seek",20)
`當一個函數的返回值是另一個函數,而返回的那個函數若是調用了其父函數內部的其它變量,
若是返回的這個函數在外部被執行,就產生了閉包。
表現形式:使函數外部可以調用函數內部定義的變量。`
閉包的使用場景
函數做爲返回值
function fn(){ var a = 10; return function(){ console.log(a); //a是自由變量,從父做用域開始找。 } } var f1 = fn(); var a = 20; f1(); //10
函數做爲參數來傳遞
function fn(){ var a = 10; return function(){ console.log(a); } } var fn1 = fn(); function fn2(fn){ var a =20; fn(); } fn2(fn1); //10
var str,a; for( a=0; a<10;a++){ str = document.createElement("a"); str.innerHTML = a + "點我" + "<br/>"; document.body.appendChild(str); (function(a){ str.addEventListener("click",function(e){ e.preventDefault(); console.log(a) }) })(a) }
同步是阻塞模式,異步是非阻塞模式。
var arr= [2,3,9,0];
arr.forEach(function(item,index){ console.log(item) // 2390 console.log(index) //0123 })
var result = arr.every(function(item,index){ if(item < 4) { return true; } }) console.log(result); //false, 由於9並不小於4
var result = arr.some(function(item,index){ if(item < 4) { return true; } }) console.log(result); //true 由於2,3,0小於4
var result = arr.sort(function(a,b){ // return a-b; //正序 return b-a; // 倒序 // return return Math.random() - 0.5; //最簡單的隨機數組排序,並不推薦 }) console.log(result); // [9, 3, 2, 0]
//map適用範圍仍是較廣的,學會思考 var result = arr.map(function(item,index){ return '<h1>' + item + '</h1>'; }) console.log(result); // ["<h1>2</h1>", "<h1>3</h1>", "<h1>9</h1>", "<h1>0</h1>"]
var result = arr.filter(function(item,index){ if(item >=3){ return true; } }) console.log(result); // [3, 9]
function formatDate(dt) { if (!dt) { //若是不傳參數,則默認爲當前時間 dt = new Date(); } var year = dt.getFullYear(); var month = dt.getMonth() + 1; var day = dt.getDate(); if (month <= 10) { month = '0' + month; } if (day <= 10) { day = '0' + day; } return year + '-' + month + '-' + day; } var date = formatDate(); console.log(date); //2019-03-23
var random = Math.random(); random = random + '0'.repeat(10); //repeat 重複10個0, 防止隨機數出現少於10位數的狀況 random = random.slice(0,10) console.log(random); //0.70728618 每次返回的只有10位數的字符串
function foreach(info, fn) { //數組處理 if(info instanceof Array) { info.forEach(fn) }else{ //對象處理 for( key in obj){ fn(key, obj[key]) } } } //使用方法 var obj = {x: '我是x',y: '我是y'}; foreach(obj, function(key,value){ console.log(value); //我是x,我是y }) var arr = [5,8,9]; foreach(arr, function(elem,index){ console.log(elem);//5,8,9 })
function bindEvent(elem,type,fn){ elem.addEventListener( type ,fn) } //使用方法 bindEvent(id,'click', function(e){ console.log(e) }) bindEvent(a,'click', function(e){ e.preventDefault(); //阻止默認事件 })
//使用代理,由父級幫忙去作 <div id="div1"> <a href="#">a1</a> <a href="#">a2</a> <span>ddd</span> <a href="#">a5</a> <!-- 動態加載更多 --> </div> div1.addEventListener('click', function(e){ if (e.target.nodeName == "A"){ alert(e.target.innerHTML) } })
//HTML結構 <div id="div1"> <a href="#">a1</a> <a href="#">a2</a> <span>ddd</span> <a href="#">a5</a> <!-- 動態加載更多 --> </div> <div id="div2">不使用代理</div> // function bindEvent(elem,type,selector, fn){ if(fn == null){ fn=selector; selector =null; } elem.addEventListener( type ,function(e){ var target; if(selector){ target = e.target; //matches() 方法用於檢測字符串是否匹配給定的正則表達式。 if(target.matches(selector)){ fn.call(target,e); } }else{ fn.call(e); } }) } //使用代理 bindEvent(div1,'click','a',function(e){ console.log(this) }) //不使用代理 bindEvent(div2,'click',function(e){ //call改變了this指向爲e console.log(this.toElement.innerHTML) })
<img src="" alt=""> //用於打點統計 <link rel="stylesheet" href=""> //使用CDN <script></script> // 使用JSONP
JS中,在函數外部沒法訪問函數內部的值,使用閉包就能夠作到。
優勢:
缺點
Cache-Control: http1.1推出,指文件緩存的有效期。