數(shù)據(jù)類型
基本數(shù)據(jù)類型:
undefined, null, boolean, number, string
引用類型:
object, function, array, date, regexp
null == undefined //true
undefined派生于null
未初始化或未聲明變量typeof都返回undefined
浮點數(shù)最高精度17位小數(shù)肉康,永遠不要測浮點值
保證浮點數(shù)計算正確性,使用內(nèi)置的toPrecision()和toFixed()
任何與NaN的操作都返回NaN
isNaN(NaN); //true
NaN == NaN; //false
數(shù)字字符串之前存在+/-都被轉(zhuǎn)為數(shù)字
"string".length返回字符串16位字符數(shù),如包含雙字節(jié)字符,length不準
字符串一旦創(chuàng)建,不能改變弱恒,除非銷毀原來的字符串,再新增字符串填充
number.toString(2);
轉(zhuǎn)型函數(shù)String(),處理對象不知道undefined,null
var a;String(a); //undefined
var b = null; String(b); //null
object實例有以下對象:
constructor;
__proto__;
isPrototypeOf(object);
hasOwnProperty("xxx");
toString();返回object字符串表示
valueOf();返回object自身
var arr = [];
Array.isArray(arr.valueOf()); //true
Array.isArray(arr.toString()); //false
with語句主要為了簡化多次編寫同一對象
with(location){
var url = href;
}
switch比較值用===
函數(shù)體內(nèi)用arguments訪問參數(shù)(非Array,類數(shù)組對象)
arguments.callee(); //callee為一個指向擁有這個arguments對象的函數(shù)
arguments.caller(); //caller為一個指向調(diào)用當(dāng)前函數(shù)對象的函數(shù)
function a(){
alert(arguments.length);
}
函數(shù)參數(shù)按值傳遞莽红,引用類型會復(fù)制引用地址
typeof對任何引用類型或null類型都會返回object
typeof undefined; //undefined
instanceof會檢測是那種類型的對象,instanceof運算符可以用來判斷某個構(gòu)造函數(shù)的prototype屬性是否存在于另外一個要檢測對象的原型鏈
typeof null, typeof new Object(), typeof function(){}, typeof [], typeof new Date(), typeof new regExp();都返回object
檢測類型用xxx instanceof Type;
js沒有塊級作用域,訪問局部變量更快邦邦,無須向上搜索
js有CG安吁,將變量設(shè)null切斷變量與引用連接釋放資源,解除引用
Array的length并非只讀
Date的getMonth從0開始
this燃辖,始終指向調(diào)用函數(shù)的對象
匿名函數(shù)鬼店,定時器中的函數(shù)默認this指向window,嚴格模式下在找不到直接調(diào)用者是this為undefined
var x = 1;
function test(){
alert(this.x);
};
test(); //1黔龟,test函數(shù)在全局調(diào)用妇智,this指向全局作用域
var y = {x:2, test:test};
y.test(); //2滥玷,test函數(shù)被y調(diào)用,this指向y
call, apply, bind
用來指定函數(shù)中this指向(重設(shè)作用域)
var a = {
x:1,
fn:function(arg1, arg2){
alert(this.x);
}
};
var b = a.fn;
b(); //undefined, this指向全局
b.call(a, 1, 2); //1, this指向a對象
b.apply(a, [1, 2]); //1, this指向a對象
var fn = b.bind(a); //bind返回一個函數(shù)
fn(1, 2); //1
創(chuàng)建對象
1.構(gòu)造函數(shù)模式
function Person(name){
this.name = name;
};
var p1 = new Person("66");
任何函數(shù)巍棱,只要通過new操作符調(diào)用惑畴,就可以作為構(gòu)造函數(shù)
構(gòu)造函數(shù)在沒有返回值的情況下,默認返回新對象實例航徙,而通過在構(gòu)造函數(shù)末尾添加return可重寫構(gòu)造函數(shù)返回值
問題:每個方法屬性都要在每個實例上重新創(chuàng)建一遍
Person中prototype如贷,實例對象p1中的__proto__都指向一個Person Prototype對象
new構(gòu)建對象的本質(zhì)
1.創(chuàng)建一個新對象
2.將構(gòu)造函數(shù)作用域分配給新對象
3.執(zhí)行構(gòu)造函數(shù),為對象添加屬性
4.返回新對象
2.原型模式
function Person(){
};
Person.prototype.name = "77";
var p1 = new Person();
p1.name; //77
var p2 = new Person();
//prototype重賦值到踏,切斷Person與原Person prototye對象的聯(lián)系
Person.prototype = {name: 66};
//77 任然指向原prototype對象
p2.name;
每個函數(shù)都有一個prototype杠袱,包含可由特定類型的所有實例共享的屬性和方法
prototype就是通過調(diào)用構(gòu)造函數(shù)而創(chuàng)建的那個對象的原型
prototype.constructor屬性包含一個指向prototype所在的指針
每創(chuàng)建一個函數(shù)都會自動創(chuàng)建一個Prototype對象
Person.prototype -> Person Prototype
p.__proto__ -> Person Prototype
Person Prototype.constructor -> Person
Person.construct;//Function
Person.prototype.construct://Person原型
p.construct;//Person原型
p.__proto__.construct;//Person原型
function SuperType(){};
var s = new SuperType();
SuperType.constructor; //Function
SuperType.prototype.constructor; //SuperType
s.constructor; //SuperType
s.__proto__.constructor; //SuperType
function SubType(){};
SubType.prototype = new SuperType();
var sub = new SubType();
SubType.constructor; //Function
SubType.prototype.constructor; //SuperType
sub.constructor; //SuperType
sub.__proto__.constructor; //SuperType
確定屬性存在于對象還是原型
function hasPrototypeProperty(object, name){
//hasOwnProperty實例屬性返回true
//in實例屬性或原型屬性都返回true
return !object.hasOwnProperty(name) && (name in object);
}
繼承
原型鏈:利用原型讓一個類型繼承另一個類型的屬性和方法(原型指向另一類型實例楣富,另一類型原型又指向另另一個類型實例)原型鏈為實現(xiàn)繼承的主要方法
function SuperType(){}
function SubType(){}
//實現(xiàn)繼承的本質(zhì)為重寫原型對象菩彬,繼承原型屬性方法和實例屬性方法
SubType.prototype = new SuperType();
1.借用構(gòu)造函數(shù)(實現(xiàn)對實例屬性和方法的繼承)
function SuperType(arg1){
this.colors = ["red"];
};
function SubType(){
//通過call調(diào)用方式創(chuàng)建自己的colors副本
//可給超類傳遞參數(shù)
SuperType.call(this, "66");
};
var s1 = new SubType();
s1.colors.push("blue");
var s2 = new SubType();
2.組合繼承
原型鏈實現(xiàn)對原型屬性和方法的繼承(所有實例共享的屬性方法)潮梯,借用構(gòu)造函數(shù)實現(xiàn)對實例屬性和方法的繼承(實例自己的屬性方法)
function SuperType(arg1){
this.colors = ["red"];
};
SuperType.prototype.say = function(){};
function SubType(arg1){
//第二次調(diào)用SuperType()
SuperType.call(this, arg1);
};
//第一次調(diào)用SuperType()
SubType.prototype = new SuperType();
問題:會調(diào)用2次超類構(gòu)造函數(shù),一次是在創(chuàng)建子類型原型時免都,一次是在子類型構(gòu)造函數(shù)內(nèi)部
匿名函數(shù)(拉姆達函數(shù))
作用:
模仿塊級作用域(function(){})(),模塊模式
執(zhí)行環(huán)境具有全局性,this常指向全局
遞歸函數(shù)
應(yīng)始終使用arguments.callee調(diào)用自己
作用域鏈
當(dāng)執(zhí)行一段JavaScript代碼(全局代碼或函數(shù))時绢陌,JavaScript引擎會創(chuàng)建為其創(chuàng)建一個作用域又稱為執(zhí)行上下文(Execution Context),然后每執(zhí)行一個函數(shù)愁铺,會建立一個對應(yīng)的作用域,從而形成了一條作用域鏈
全局變量默認掛載在window對象下
閉包:有權(quán)訪問另一個函數(shù)作用域中變量的函數(shù)
在函數(shù)的內(nèi)部創(chuàng)建另一個函數(shù)获黔,就創(chuàng)建了一個閉包堵未,閉包有權(quán)訪問父級函數(shù)內(nèi)部所有變量,通常函數(shù)作用域中所有變量會在函數(shù)執(zhí)行完畢后銷毀,但當(dāng)函數(shù)返回了一個閉包世落,該函數(shù)的作用域?qū)⒁恢北4嬖趦?nèi)存直到閉包函數(shù)銷毀
閉包應(yīng)用:
1.模擬類的私有屬性
function a(){
var b = 66;
return function(){
b;
}
}
2.讓變量值始終保持在內(nèi)存
var fs = [];
var fs2 = [];
for(var i = 0; i<10; i++){
fs.push((function(arg){
return function(){return arg};
})(i));
fs2.push(function(){return i});
}
fs[2](); //2, var i 換成let i效果同
fs2[2]();//10
閉包會攜帶父級函數(shù)的全部作用域鏈武花,因此比其他函數(shù)占用更多內(nèi)存
IIFE(立即執(zhí)行函數(shù)表達式)
1.模塊封裝
2.jquery等自定義插件
事件
事件冒泡,IE的事件流叫冒泡,從下往上
事件捕獲争群,Netscape提出的另一種事件流,從上往下
DOM事件流:事件捕獲,處于目標(biāo)階段驹碍,事件冒泡浮还,IE不支持
DOM0級事件處理程序
btn.onclick = function(){};
DOM2級事件處理程序,第3個參數(shù)為true,在捕獲階段調(diào)用事件處理程序, 為false表示在冒泡階段調(diào)用事件處理程序
btn.addEventListener("click", function(){}, false);
IE事件處理
btn.attachEvent("onclick", function(){});
btn.detachEvent("onclick", function(){});
取消冒泡
e.stopPropagation();
IE window.event.cancelBubble = true;
事件代理
JavaScript事件代理則是一種簡單的技巧普泡,通過它你可以把事件處理器添加到一個父級元素上,這樣就避免了把事件處理器添加到多個子級元素上审编。當(dāng)我們需要對很多元素添加事件的時候垒酬,可以通過將事件添加到它們的父節(jié)點而將事件委托給父節(jié)點來觸發(fā)處理函數(shù)砰嘁。這主要得益于瀏覽器的事件冒泡機制。事件代理用到了兩個在JavaSciprt事件中常被忽略的特性:事件冒泡以及目標(biāo)元素秀撇。
function getEventTarget(e) {
e=e||window.event;
return e.target||e.srcElement;
}
頁面加載事件
document.ready表示文檔結(jié)構(gòu)加載完畢
document.onload表示頁面圖片,內(nèi)容都加載完畢
變量提升
javascript變量提升
提升變量自動賦值為null
同源策略
同源指域名夜矗,協(xié)議泛范,端口相同
限制Cookie, localStrorage, indexDB,DOM,Ajax(CORS)
CORS需要瀏覽器服務(wù)器同時支持
簡單請求(HEAD, GET, POST),瀏覽器發(fā)現(xiàn)Ajax為跨域逛揩,自動添加Origin標(biāo)識本次請求來源(協(xié)議+域名+端口)
服務(wù)器端發(fā)現(xiàn)Origin指定源在許可范圍內(nèi),會返回一個帶有Access-Control-Allow-Origin字段麸俘,瀏覽器知道請求沒問題辩稽,否則出錯
Access-Control-Allow-Credentials是否允許發(fā)送Cookie,默認Cookie不包括在CORS請求中(Access-Control-Allow-Origin必須指明明確域名,服務(wù)器指定該字段為true,同時Ajax請求中要打開xhr.withCredentials = true)
非簡單請求(PUT,DELETE,Content-Type為application/json),會在正式通信前从媚,增加一次HTTP預(yù)檢請求(preflight),先詢問服務(wù)器域名是否在許可名單逞泄,以及可以使用哪些HTTP動詞,頭信息字段拜效。服務(wù)器端許可后喷众,會返回
Access-Control-Request-Method:PUT(許可的HTTP請求方法)
Access-Control-Request-Headers:X-Custom-Header(許可的自定義頭部信息)
Access-Control-Max-Age:指定預(yù)檢請求有效時間(可選)
XMLHttpRequest
var xmlhttp = null;
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}
else if(window.ActiveXObject){
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
if(xmlhttp != null){
xmlhttp.onreadystatechange = stateChange;
xmlhttp.open("GET", url, true);
xmlhttp.send(null);
}
function stateChange(){
//readyState為0(uninitialized)到4(complete)變化
if(xmlhttp.readyState == 4){
if(xmlhttp.status == 200){
}
}
}
網(wǎng)絡(luò)安全
XSS攻擊(跨域腳本攻擊)
栗子:在輸入框輸入<script>惡意腳本</script>
防范:輸入過濾為安全的html,Html encode
CSRF攻擊(跨站請求偽造攻擊)
栗子:盜用受害人身份
防范:添加輸入驗證碼操作紧憾,Refer Check到千,請求帶token服務(wù)器端驗token
SSL攻擊(中間人攻擊)
偽造服務(wù)器,偽造秘鑰證書
SSL協(xié)議
1.使用證書確認用戶和服務(wù)器
2.數(shù)據(jù)尾部添加校驗碼赴穗,防止中途篡改
3.加密傳輸數(shù)據(jù)和校驗碼憔四,防止中途竊取