1.undefined和null的區(qū)別
null: Null類型,代表“空值”县踢,代表一個空對象指針捏悬,使用typeof運算得到 “object”佩脊,所以你可以認(rèn)為它是一個特殊的對象值症昏。
undefined: Undefined類型随闽,當(dāng)聲明了一個變量而未初始化時,得到的就是undefined肝谭,使用typeof運算得到 “undefined”橱脸。
2.js基本的數(shù)據(jù)類型
ECMAScript中有5中簡單數(shù)據(jù)類型(也稱為基本數(shù)據(jù)類型): Undefined、Null分苇、Boolean、Number和String屁桑。
還有1中復(fù)雜的數(shù)據(jù)類型————Object医寿。Object本質(zhì)上是由一組無序的名值對組成的。
而 typeof 的返回類型包含:undefined蘑斧、boolean靖秩、string、number竖瘾、object 和 function沟突。
3.原生獲取元素的方法
JS獲取DOM元素的方法(8種)
通過ID獲取(getElementById)
通過name屬性(getElementsByName)
通過類名class(getElementsByClassName)
通過標(biāo)簽名(getElementsByTagName)
通過選擇器獲取一個元素(querySelector)
通過選擇器獲取一組元素(querySelectorAll)
獲取html的方法(document.documentElement)
document.documentElement是專門獲取html這個標(biāo)簽的
獲取body的方法(document.body)
document.body是專門獲取body這個標(biāo)簽的捕传。
4.css選擇器
①.ID選擇器 #
②.類選擇器 .
③.標(biāo)簽選擇器 p,div,span
④.偽類選擇器 :link :active :visited :hover
⑤.通用選擇器 *
⑥.屬性選擇器 [attr='']
5.js中的new關(guān)鍵字
一惠拭、認(rèn)識new運算符:
function Animal(name){ // 創(chuàng)建Animal構(gòu)造函數(shù)
this.name = name;
}
Animal.color = "black";
Animal.prototype.say = function(){
console.log("I'm " + this.name);
};
var cat = new Animal("cat"); // 創(chuàng)建cat實例
console.log(
cat.name, //cat
cat.color //undefined
);
cat.say(); //I'm cat
console.log(
Animal.name, //Animal
Animal.color //black
);
Animal.say(); //Animal.say is not a function
1、代碼解讀
1-3行---創(chuàng)建了一個函數(shù)Animal,并在其this上定義了屬性:name职辅,name的值是函數(shù)被執(zhí)行時的形參棒呛。
第4行---在Animal對象(Animal本身是一個函數(shù)對象)上定義了一個靜態(tài)屬性:color,并賦值“black”域携。
5-7行---在Animal函數(shù)的原型對象prototype上定義了一個say()方法簇秒,say方法輸出了this的name值。
第8行---通過new關(guān)鍵字創(chuàng)建了一個新對象cat秀鞭。
10-14行---cat對象嘗試訪問name和color屬性趋观,并調(diào)用say方法。
16-20行---Animal對象嘗試訪問name和color屬性锋边,并調(diào)用say方法皱坛。
2、重點解析
第8行代碼是關(guān)鍵:
var cat = new Animal("cat");
JS引擎執(zhí)行這句代碼時宠默,在內(nèi)部做了很多工作麸恍,用偽代碼模擬其工作流程如下:
new Animal("cat") = {
var obj = {};
obj.__proto__ = Animal.prototype;
var result = Animal.call(obj,"cat");
return typeof result === 'object'?result:obj;
}
代碼解析:
(1)創(chuàng)建一個空對象obj;
(2)把obj的__ proto__ 指向Animal的原型對象prototype,此時便建立了obj對象的原型鏈:obj->Animal.prototype->Object.prototype->null
如果你不了解JS原型鏈搀矫,請先閱讀:JS原型和原型鏈
(3)在obj對象的執(zhí)行環(huán)境調(diào)用Animal函數(shù)并傳遞參數(shù)“cat”抹沪。 相當(dāng)于var result = obj.Animal("cat")。當(dāng)這句執(zhí)行完之后瓤球,obj便產(chǎn)生了屬性name并賦值為"cat"融欧。
關(guān)于JS中call的用法請閱讀:JS的call和apply
(4)考察第3步返回的返回值,如果無返回值或者返回一個非對象值卦羡,則將obj返回作為新對象噪馏;否則會將返回值作為新對象返回。
理解new的運行機制以后绿饵,我們知道cat其實就是過程(4)的返回值欠肾,因此我們對cat對象的認(rèn)知就多了一些:
cat.__ proto__ == Animal.prototype
Animal.prototype.__ proto__ == Object.prototype
Object.prototype.__ proto__ == null
__ proto__和prototype 以下四點需要謹(jǐn)記:
1.每個對象都具有一個名為__ proto__的屬性;
2.每個構(gòu)造函數(shù)(構(gòu)造函數(shù)標(biāo)準(zhǔn)為大寫開頭拟赊,如Function()刺桃,Object()等等JS中自帶的構(gòu)造函數(shù),以及自己創(chuàng)建的)都具有一個名為prototype的方法(注意:既然是方法吸祟,那么就是一個對象(JS中函數(shù)同樣是對象)瑟慈,所以prototype同樣帶有__ proto__屬性);
3.每個實例對象的__ proto__屬性指向自身構(gòu)造函數(shù)的prototype屋匕;(eg: cat__proto __ == Animal.prototype)
4.原型上綁定的屬性或方法葛碧,只能在new 出的實例上使用。(eg: Animal.prototype.say 的say方法过吻,只能在cat實例上使用进泼。)
所以cat的原型鏈?zhǔn)牵?/p>
cat->Animal.prototype->Object.prototype->null
cat上新增了一個屬性:name屬性。
所以此時cat對象為:
:實例對象(cat)的 __ proto __ == 構(gòu)造函數(shù)(Animal)的prototype。
即:cat.__ proto __ == Animal.prototype
(注:#proto前后無空格缘琅,若不輸入空格粘都,在此無法顯示__,故在此加上前后空格)
:實例對象(cat)的constructor == 構(gòu)造函數(shù)(Animal)刷袍。
即:cat.constructor == Animal
分析完了cat的產(chǎn)生過程翩隧,我們再看看輸出結(jié)果:
cat.name -> 在過程(3)中,obj對象就產(chǎn)生了name屬性呻纹。因此cat.name就是這里的obj.name
cat.color -> cat會先查找自身的color堆生,沒有找到便會沿著原型鏈查找,在上述例子中雷酪,我們僅在Animal對象上定義了color,并沒有在其原型鏈上定義淑仆,因此找不到。
cat.say -> cat會先查找自身的say方法哥力,沒有找到便會沿著原型鏈查找蔗怠,在上述例子中,我們在Animal的prototype上定義了say,因此在原型鏈上找到了say方法吩跋。
另外寞射,在say方法中還訪問this.name,這里的this指的是其調(diào)用者obj锌钮,因此輸出的是obj.name的值桥温。
對于Animal來說,它本身也是一個對象梁丘,因此侵浸,它在訪問屬性和方法時也遵守上述查找規(guī)則,所以:
Animal.color -> "black"
Animal.name -> "Animal" , Animal先查找自身的name,找到了name,注意:但這個name不是我們定義的name,而是函數(shù)對象內(nèi)置的屬性氛谜。
一般情況下掏觉,函數(shù)對象在產(chǎn)生時會內(nèi)置name屬性并將函數(shù)名作為賦值(僅函數(shù)對象)。
Animal.say -> Animal在自身沒有找到say方法值漫,也會沿著其原型鏈查找履腋,話說Animal的原型鏈?zhǔn)鞘裁茨兀?/p>
Animal.__ proto __ == Function.prototype
Function.prototype.__ proto__ == Object.prototype
Object.prototype.__ proto__ == null
所以Animal的原型鏈?zhǔn)牵?/p>
Animal->Function.prototype->Object.prototype->null
二、new存在的意義
認(rèn)識了new運算符之后惭嚣,我們再回到開篇提到的問題:JS中萬物皆對象,為什么還要通過new來產(chǎn)生對象悔政?要弄明白這個問題晚吞,我們首先要搞清楚cat和Animal的關(guān)系。
通過上面的分析谋国,我們發(fā)現(xiàn)cat繼承了Animal中的部分屬性槽地,因此我們可以簡單的理解:Animal和cat是繼承關(guān)系。
我們用這個方法來判斷一下cat和Animal
cat instanceof Animal; //true
從執(zhí)行結(jié)果看:cat確實是Animal實例對象,要想證實這個結(jié)果捌蚊,我們再來了解一下JS中instanceof的判斷規(guī)則:
var L = cat.__ proto __;
var R = B.prototype;
if(L === R) return true;
如果A的__ proto __ 等價于 B的prototype集畅,就返回true。
在new的執(zhí)行過程(2)中缅糟,cat的proto指向了Animal的prototype挺智,所以cat和Animal符合instanceof的判斷結(jié)果。因此窗宦,我們認(rèn)為:cat是Animal的實例對象赦颇。
簡單的總結(jié)語
在javascript中, 通過new可以產(chǎn)生原對象的一個實例對象,而這個實例對象繼承了原對象的屬性和方法赴涵。因此媒怯,new存在的意義在于它實現(xiàn)了javascript中的繼承,而不僅僅是實例化了一個對象髓窜!
6.GET和POST請求方式的區(qū)別
GET和POST是HTTP請求的兩種基本方法扇苞。
最直觀的區(qū)別就是GET把參數(shù)包含在URL中,POST通過request body傳遞參數(shù)寄纵。
①.GET請求只能進行url編碼鳖敷,而POST支持多種編碼方式。
②.GET請求參數(shù)會被完整保留在瀏覽器歷史記錄里擂啥,而POST中的參數(shù)不會被保留哄陶。
③.GET請求在URL中傳送的參數(shù)是有長度限制的,而POST沒有哺壶。
④.對參數(shù)的數(shù)據(jù)類型屋吨,GET只接受ASCII字符,而POST沒有限制山宾。
⑤.POST比GET更安全至扰,因為GET參數(shù)直接暴露在URL上,所以不能用來傳遞敏感信息资锰。
⑥.GET參數(shù)通過URL傳遞敢课,POST放在Request body中。
7.rem.js
適配移動端的Rem.js:
window.onload = function(){
/*750代表設(shè)計師給的設(shè)計稿的寬度绷杜,你的設(shè)計稿是多少直秆,就寫多少;100代表換算比例,這里寫100是
為了以后好算,比如鞭盟,你測量的一個寬度是100px,就可以寫為1rem,以及1px=0.01rem等等*/
getRem(750,100)
};
window.onresize = function(){
getRem(750,100)
};
function getRem(pwidth,prem){
var html = document.getElementsByTagName("html")[0];
var oWidth = document.body.clientWidth || document.documentElement.clientWidth;
html.style.fontSize = oWidth/pwidth*prem + "px";
}
8.數(shù)組去重:
①.第一種方法
var arr=[1,2,3,4,5,6,7,6,5,4,3];
var newArr=[];
for(var i=0; i<arr.length; i++){
if(arr.indexOf(arr[i])==i){
newArr.push(arr[i])
}
}
console.log(newArr);
②第二種方法
var arr=[1,2,3,4,5,6,7,6,5,4,3];
var newArr=[];
for(var i=0; i<arr.length; i++){
if(newArr.indexOf(arr[i])==-1){
newArr.push(arr[i])
}
}
console.log(newArr);
③第三種方法
var arr=[1,2,3,4,5,6,7,6,5,4,3];
function quchong(arr){
var res = [arr[0]]
for(var i=1; i<arr.length; i++){
var repeat = false;
for(var j=0; j<res.length; j++){
if(arr[i] == res[j]){
repeat = true;
break;
}
}
if(!repeat){
res.push(arr[i]);
}
}
console.log(res);
}
quchong(arr)
9.駝峰命名法
var str='get-element-by-id';
function join(str){
var arr=str.split('-');
var newStr='';
for(var i=0;i<arr.length;i++){
if(i==0){
newStr+=arr[i]
}else{
newStr+=arr[i].slice(0,1).toUpperCase()+arr[i].slice(1);
}
}
console.log(newStr);
}
join(str);
10.垂直水平居中
①
#box {
background-color: #FF8C00;
width: 300px;
height: 300px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -50px;
margin-top: -50px;
}
.inner {
background-color: #F00;
display: inline-block;
width: 100px;
height: 100px;
}
②
#box {
background-color: #FF8C00;
width: 300px;
height: 300px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50px,-50px);
}
.inner {
background-color: #F00;
display: inline-block;
width: 100px;
height: 100px;
}
③
#box {
background-color: #FF8C00;
width: 300px;
height: 300px;
/*flex*/
display: flex;
justify-content: center;
align-items: center;
}
.inner {
background-color: #F00;
display: inline-block;
width: 100px;
height: 100px;
}
④
#box {
background-color: #FF8C00;
width: 300px;
height: 300px;
/*table-cell*/
display: table-cell;
vertical-align: middle;//垂直居中
}
.inner {
background-color: #F00;
display: inline-block;
margin: auto;//水平居中
width: 100px;
height: 100px;
}