11、數(shù)據(jù)類型檢測與toString方法的理解
1,typeof value (檢測一個(gè)值的類型:原始類型或者引用類型)
檢測當(dāng)前值的數(shù)據(jù)類型,返回的結(jié)果:首先是一個(gè)字符串,其次字符串中包含了對(duì)應(yīng)的數(shù)據(jù)類型
[TYPEOF局限]
1、typeof null->"object" null為空對(duì)象指針 但是null不是對(duì)象數(shù)據(jù)類型;
2,不能具體細(xì)分是數(shù)組還是正則還是對(duì)象中的其他值,因?yàn)槭褂胻ypeof檢測數(shù)據(jù)類型對(duì)于對(duì)象數(shù)據(jù)類型的值返回的都是"object"
BAT面試題:
console.log(typeof typeof []);:
-> typeof [] =>"object"
-> typeof "object" =>"string"
2,A instanceof B
檢測A實(shí)例是否屬于B這個(gè)類(可以具體細(xì)分一個(gè)對(duì)象是數(shù)組還是正則)A必須是對(duì)象數(shù)據(jù)類型,只要B在A的原型鏈上出現(xiàn)過,檢測結(jié)果就是true;
[instanceof局限性]
1,不能用來檢測和處理字面量方式創(chuàng)建出來的基本數(shù)據(jù)類型值;
- 對(duì)于基本數(shù)據(jù)類型來說,字面量方式創(chuàng)建出來的結(jié)果和實(shí)例方式創(chuàng)建出來的結(jié)果是有一定區(qū)別的,從嚴(yán)格意義上來講,只有實(shí)例創(chuàng)建出來的結(jié)果才是標(biāo)準(zhǔn)的對(duì)象,數(shù)據(jù)類型值也是標(biāo)準(zhǔn)的基本數(shù)據(jù)類型,也是標(biāo)準(zhǔn)的內(nèi)置類的實(shí)例;對(duì)于字面量方式創(chuàng)建出來的結(jié)果是基本數(shù)據(jù)類型的值,不是嚴(yán)格的實(shí)例,但是由于JS的松散特點(diǎn),導(dǎo)致了可以使用 內(nèi)置類.prototype上提供的方法;
2,只要在原型鏈上能找到就返回true,所以在類的原型繼承中,我們最后用instanceof檢測出來的結(jié)果未必準(zhǔn)確
3,constructor
獲取當(dāng)前實(shí)例所屬類的構(gòu)造函數(shù)的屬性 與instanceof檢測類似 可以處理基本數(shù)據(jù)類型的檢測,一般檢測不了object數(shù)據(jù)類型;
[constructor局限性]
1,我們可以把類的原型進(jìn)行重寫,在重寫的過程中很有可能出現(xiàn)把之前的constructor給覆蓋了,這樣檢測出來的結(jié)果就是不準(zhǔn)確的
4,Object.prototype.toString.call().slice(8,-1);
最常用最準(zhǔn)確的,借用Object基類原型上的toString方法,在執(zhí)行這個(gè)方法的時(shí)候,讓方法中的THIS指向需要檢測的值,從而獲取到當(dāng)前值所屬類的詳細(xì)信息,進(jìn)而檢測出對(duì)應(yīng)的數(shù)據(jù)類型
原理:Object.prototype.toString它的作用是返回當(dāng)前方法的執(zhí)行主體(方法中的this)所屬類的詳細(xì)信息
var obj={name:"珠峰"};
console.log(obj.toString());toString中的this是obj,返回的是obj所屬類的信息
"[object Object]"
- 第一個(gè)object代表當(dāng)前實(shí)例是對(duì)象數(shù)據(jù)類型的(固定的)
- 第二個(gè)Object代表的是obj所屬的類是Object
toString的理解:
1,對(duì)于Number、String、Boolean、Array、RegExp、Date、Function原型上的toString方法都是把當(dāng)前數(shù)據(jù)類型轉(zhuǎn)換為字符串的類型(它們的作用僅僅是用來轉(zhuǎn)換為字符串的)要把Object類型的值轉(zhuǎn)換為字符串的話可以用JSON.stringify(Object),例如JSON.stringify({name:"珠峰"})-》{"name":"珠峰"}
2,Object.prototype.toString方法并不是用來轉(zhuǎn)換為字符串的({name:"珠峰"}).toString()->"[object Object]"
模擬內(nèi)置isArray所寫檢測數(shù)據(jù)類型的方法:
//根據(jù)老師的方法修改版,親測可用
~function () {
var obj = {
isNumber: 'Number',
isString: 'String',
isBoolean: 'Boolean',
isNull: 'Null',
isUndefined: 'Undefined',
isPlanObject: 'Object',
isArray: 'Array',
isRegExp: 'RegExp',
isFunction: 'Function'
};
var check = {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
//給check對(duì)象添加每個(gè)類的檢測方法名和檢測方法
check[key] = (function (value) {
return function (val) {
return value===(Object.prototype.toString.call(val).slice(8,-1));
}
})(obj[key]);
}
}
window.check = check;
}();
12、null和undefined的區(qū)別匯總
null==undefined =>true
null===undefined =>false
0和空字符串與null和undefined的區(qū)別:
null和undefined相比于0和空字符串占用的內(nèi)存更少
null:
空對(duì)象指針->沒有具體的值->一般都是我們手動(dòng)設(shè)置初始值為null,后期會(huì)給其賦值;
undefined:
未定義->連東西都沒有->一般都是瀏覽器默認(rèn)的值;
用null的幾種情況:
1,設(shè)定變量初始值:我們設(shè)定一個(gè)變量,后期我們要使用,那么我們設(shè)置默認(rèn)值為null
2,釋放堆內(nèi)存:在JS內(nèi)存釋放中,我們想釋放一個(gè)堆內(nèi)存,就讓其值變?yōu)閚ull即可
3,在DOM元素獲取中,不存在則結(jié)果為null:我們通過DOM中提供的屬性和方法獲取頁面中的某一個(gè)元素標(biāo)簽,如果這個(gè)標(biāo)簽不存在,獲取的結(jié)果是null,而不是undefined
4,在正則的exec/字符串的match捕獲中,如果當(dāng)前要捕獲的字符串和正則不匹配的話,捕獲到的結(jié)果為null;
用undefined的集中情況:
1,JS預(yù)解釋的時(shí)候只聲明未定義,默認(rèn)值為undefined;
2,在一個(gè)函數(shù)中,如果沒有寫return,或者return后什么都沒寫,默認(rèn)返回值為undefined;
3,函數(shù)中設(shè)置了形參,但是執(zhí)行的時(shí)候如果沒有傳遞參數(shù)值,那么形參默認(rèn)值為undefined;
4,獲取一個(gè)對(duì)象的屬性名對(duì)應(yīng)屬性值的時(shí)候,如果這個(gè)屬性名不存在的話屬性值為undefined;
5,嚴(yán)格模式下,this前沒有明確的執(zhí)行主體,this就是undefined
6,用來檢測瀏覽器兼容問題,不兼容的話返回undefined
13、函數(shù)數(shù)據(jù)類型
函數(shù)
函數(shù):具備一定功能的方法;
<font color=red>創(chuàng)建函數(shù):</font>
1.聲明一個(gè)函數(shù)名(函數(shù)用function,變量用var)
2.開辟一個(gè)新的內(nèi)存空間(有一個(gè)16進(jìn)制的地址),然后把函數(shù)體中實(shí)現(xiàn)功能的JS代碼按照"字符串"的格式存儲(chǔ)在內(nèi)存中
3.把空間地址賦值給函數(shù)名,此時(shí)函數(shù)名就可以和函數(shù)體本身關(guān)聯(lián)到一起了;
function 函數(shù)名(){
函數(shù)體:實(shí)現(xiàn)某一功能的JS代碼
}
<font color=red>函數(shù)執(zhí)行:</font>
1.函數(shù)執(zhí)行的時(shí)候會(huì)形成一個(gè)私有的作用域,提供一個(gè)環(huán)境供函數(shù)體中的代碼執(zhí)行;
2.把創(chuàng)建的時(shí)候存儲(chǔ)的字符串變?yōu)檎嬲腏S代碼,在私有作用域中自上而下執(zhí)行
<font color=red>注意:</font>一個(gè)函數(shù)可以被執(zhí)行N次,每一次執(zhí)行相互之間互不干擾(后面會(huì)學(xué)習(xí)兩者之間建立的間接關(guān)系)
形參:形式參數(shù)(變量),函數(shù)的入口,形參也相當(dāng)于創(chuàng)建了一個(gè)私有變量
實(shí)參:函數(shù)執(zhí)行傳遞給函數(shù)的具體值就是實(shí)參
函數(shù)本身也會(huì)有一些自己的屬性
-->length:0 形參的個(gè)數(shù)
-->name:"Fn" 函數(shù)名
-->prototype 類的原型,在原型上定義的方法都是當(dāng)前Fn這個(gè)類實(shí)例的公
有方法
-->_proto_ 把函數(shù)當(dāng)做一個(gè)普通的對(duì)象,指向Function這個(gè)類的原型
call apply bind
call
fn.call(context,para1,…)
<font color=red>在借用數(shù)組原型上的方法把類數(shù)組轉(zhuǎn)化為數(shù)組的時(shí)候,IE低版本瀏覽器中,元素集合或者節(jié)點(diǎn)集合這些類數(shù)組是無法借用slice轉(zhuǎn)換的會(huì)報(bào)錯(cuò)“不是Javascript對(duì)象”;</font>
Function.prototype上的call方法的實(shí)現(xiàn)原理
Function.prototype.call=function(context){
//先明確此方法中的this指向的是call點(diǎn)前面的執(zhí)行主體,即調(diào)用此方法的主體
1、讓此方法中的this(call點(diǎn)前面的執(zhí)行主體)里面的this關(guān)鍵字指向context
2、讓此方法中的this(call點(diǎn)前面的執(zhí)行主體)執(zhí)行;
//以下為第二步:讓this執(zhí)行,即call點(diǎn)前面的執(zhí)行主體執(zhí)行;
this()
}
function fn1(){
console.log(1);
}
function fn2(){
console.log(2);
}
fn1.call(fn2);//1
fn1.call.call.call.call(fn2);//2
把方法執(zhí)行,并且讓方法中的this改變?yōu)閏ontext,都是給fn傳遞的實(shí)參
//非嚴(yán)格模式下
function fn(){
console.log(this);
}
fn.call(1);//1
fn.call();//不傳遞參數(shù)時(shí)默認(rèn)為window
fn.call(null);//傳遞null也為window
fn.call(undefined);//傳遞undefined也為window
//JS嚴(yán)格模式下
如果不傳則默認(rèn)為undefined
傳的話傳的是什么就修改為什么;
apply
apply的語法和call基本一致,作用原理也基本一致,唯一的區(qū)別:apply把傳遞給函數(shù)的實(shí)參以數(shù)組形式存放(但是也相當(dāng)于在給函數(shù)一個(gè)個(gè)的傳遞實(shí)參值)
bind(bind方法返回的是一個(gè)新的函數(shù)和原函數(shù)空間地址不同);
第一個(gè)參數(shù)為要改變的執(zhí)行主體中的this關(guān)鍵字,
第一個(gè)之后的參數(shù)都是執(zhí)行主體執(zhí)行的時(shí)候需要傳遞給執(zhí)行主體的參數(shù),傳遞給執(zhí)行主體的參數(shù)會(huì)放在執(zhí)行主體自帶的參數(shù)之前;
改變函數(shù)中this關(guān)鍵字,在IE6-8下不兼容;它和call(以及apply)改變this的原理不一樣
預(yù)先讓fn中的this指向opp,此時(shí)fn沒有執(zhí)行,只有fn執(zhí)行的時(shí)候才起作用;
bind方法兼容IE6-8版
var flag='getComputedStyle' in window;
Function.prototype.myBind=function (context) {
context=context||window;
var that=this;
var outerArg=Array.prototype.slice.call(arguments,1);
//標(biāo)準(zhǔn)瀏覽器下
if(flag){
return this.bind.apply(this,arguments);
}
//IE6-8下
return function () {
//定義一個(gè)變量接收形參事件對(duì)象
var innerArg=Array.prototype.slice.call(arguments);
that.apply(context,outerArg.concat(innerArg));
}
}
例如:點(diǎn)擊盒子的時(shí)候,執(zhí)行fn,并讓其中的this改變?yōu)閛pp
function fn(){
console.log(this);
}
oBox.onclick=fn.call(opp);/無法實(shí)現(xiàn),還沒有點(diǎn)擊的時(shí)候,fn已經(jīng)執(zhí)行了,只是把fn的返回結(jié)果給了onclick
oBox.onclick=fn.bind(opp);//完美實(shí)現(xiàn),點(diǎn)擊的時(shí)候fn才執(zhí)行,并預(yù)先讓fn中的this變?yōu)閛pp;
在真實(shí)項(xiàng)目中,我們把實(shí)現(xiàn)一個(gè)具體功能的代碼封裝在函數(shù)中:
好處:
1:減少了冗余代碼,開發(fā)效率高;
2:封裝在一個(gè)函數(shù)中,頁面中就基本上很難出現(xiàn)重復(fù)一樣的代碼了,減少了頁面中代碼的冗余度,提高了代碼的重復(fù)利用率:低耦合高內(nèi)聚;
我們把以上的特點(diǎn)稱之為函數(shù)封裝(OOP面向?qū)ο缶幊趟枷?,需要我們掌握的就是類的繼承、封裝、多態(tài))
函數(shù)的核心原理
函數(shù)作為引用數(shù)據(jù)類型的一種,也是按照地址來操作的,私有作用域中不帶var的聲明都是給window設(shè)置的屬性;
函數(shù)存在了多面性
1)作為普通函數(shù)(fn()):它本身就是一個(gè)普通的函數(shù),執(zhí)行的時(shí)候形成私有的作用域(閉包),形參賦值,預(yù)解釋,代碼執(zhí)行,執(zhí)行完成后棧內(nèi)存銷毀/不銷毀
2)作為類,即構(gòu)造函數(shù)(new Fn();):它有自己的實(shí)例,也有一個(gè)叫做prototype屬性是自己的原型,它的實(shí)例都可以指向自己的原型
3)作為普通對(duì)象(fn.aaa):和var obj={}中的obj一樣,就是一個(gè)普通的對(duì)象,它作為對(duì)象可以有一些自己的私有屬性,也可以通過____proto____找到Function.prototype
- 所有的函數(shù)都可以調(diào)取Function.prototype(類也是函數(shù))上的方法:如call、apply、bind
- 所有的對(duì)象都可以調(diào)取Object.prototype(函數(shù)也是對(duì)象)上的方法:如toString、hasOwnProperty
普通函數(shù)執(zhí)行和構(gòu)造函數(shù)執(zhí)行的區(qū)別
構(gòu)造函數(shù)執(zhí)行的時(shí)候,也是先形成一個(gè)私有作用域,形參賦值,變量提升,在代碼從上而下執(zhí)行之前,構(gòu)造函數(shù)有特殊的操作:
瀏覽器會(huì)在當(dāng)前的作用域中默認(rèn)創(chuàng)建一個(gè)對(duì)象數(shù)據(jù)類型的值,并且會(huì)讓構(gòu)造函數(shù)中的this指向創(chuàng)建的這個(gè)對(duì)象。然后JS代碼再執(zhí)行,代碼執(zhí)行完成后,即使函數(shù)中沒有寫return,在構(gòu)造函數(shù)模式中:瀏覽器會(huì)默認(rèn)的把創(chuàng)建的對(duì)象返回到函數(shù)外面
<font color=red>總結(jié):</font>
- 構(gòu)造函數(shù)執(zhí)行期間,既具備函數(shù)執(zhí)行的一面,也同時(shí)具備自己獨(dú)有的操作:在構(gòu)造函數(shù)執(zhí)行期間,瀏覽器會(huì)默認(rèn)創(chuàng)建一個(gè)對(duì)象,這個(gè)對(duì)象就是當(dāng)前這個(gè)構(gòu)造函數(shù)(類)實(shí)例,函數(shù)執(zhí)行完成后,瀏覽器會(huì)默認(rèn)的把這個(gè)實(shí)例返回。所以new Fn()執(zhí)行,F(xiàn)n是一個(gè)類,返回的結(jié)果就是Fn這個(gè)類的一個(gè)實(shí)例。
阿里面試題執(zhí)行順序總結(jié)
new Foo.getName();
new Foo().getName();
new new Foo().getName();
執(zhí)行順序總結(jié):(經(jīng)驗(yàn)之談目前來說準(zhǔn)確)
<font color=red>1、new 操作符只能new構(gòu)造函數(shù),否則會(huì)報(bào)錯(cuò),xxx is not a constructor
2、new碰到()就會(huì)把new與()之間的當(dāng)成構(gòu)造函數(shù)處理,所以會(huì)先執(zhí)行new與()之間的運(yùn)算,之后再new。<font>
棧內(nèi)存:
- 作用域(全局/私有作用域):提供一個(gè)供JS代碼執(zhí)行的環(huán)境;執(zhí)行JS代碼的
- 基本數(shù)據(jù)類型的值是直接存放在棧內(nèi)存中的
銷毀:
+ 一般情況下,函數(shù)執(zhí)行形成棧內(nèi)存,函數(shù)執(zhí)行完,瀏覽器會(huì)把形成的棧內(nèi)存自動(dòng)釋放;有時(shí)候執(zhí)行完成,棧內(nèi)存不能被釋放。
全局作用域在加載頁面的時(shí)候執(zhí)行,在關(guān)掉頁面的時(shí)候銷毀;
堆內(nèi)存:
只要遇到對(duì)象數(shù)據(jù)類型或函數(shù)數(shù)據(jù)類型,瀏覽器就會(huì)創(chuàng)建一個(gè)堆內(nèi)存。存儲(chǔ)引用數(shù)據(jù)類型值的
所有的引用數(shù)據(jù)類型,他們需要存儲(chǔ)的內(nèi)容都放在堆內(nèi)存中(相當(dāng)于一個(gè)倉庫,目的是存儲(chǔ)信息的)
- 對(duì)象會(huì)把鍵值對(duì)儲(chǔ)存起來
- 函數(shù)會(huì)把JS代碼當(dāng)做字符串儲(chǔ)存起來
- 銷毀:
- var o={}; 當(dāng)前對(duì)象對(duì)應(yīng)的堆內(nèi)存被變量o占用著呢,堆內(nèi)存是無法銷毀的
- o=null; null空對(duì)象指針(不指向任何的堆內(nèi)存),此時(shí)上一次的堆內(nèi)存就沒有被占用了,谷歌瀏覽器會(huì)在空閑時(shí)間把沒有被占用的堆內(nèi)存自動(dòng)釋放(銷毀/回收)
定義變量的時(shí)候帶var和不帶var的區(qū)別?
在全局作用域中,帶不帶var都一樣,都相當(dāng)于聲明了一個(gè)全局變量,給全局對(duì)象設(shè)置了一個(gè)新的屬性名,但是不帶var的不能提前聲明,所以在賦值前不能提前調(diào)用;
在局部作用域中,帶var的話聲明的都是私有變量,不帶var的話聲明的都是全局變量,也相當(dāng)于給window設(shè)置了一個(gè)屬性,也不能提前調(diào)用。
普通函數(shù)執(zhí)行步驟:形成一個(gè)私有作用域
1.形參賦值
2.變量提升(形參賦值后,如果有函數(shù)聲明且與形參名字相同,則覆蓋形參的值,var聲明相當(dāng)于重復(fù)聲明,不會(huì)覆蓋形參的值)
3.代碼從上到下執(zhí)行
4.棧內(nèi)存銷毀、不銷毀;
變量提升
在
當(dāng)前作用域中,JS代碼從上而下執(zhí)行之前,瀏覽器會(huì)把所有帶var和function關(guān)鍵字的進(jìn)行提前聲明,函數(shù)聲明和定義同時(shí)完成;(只對(duì)當(dāng)前作用域下的變量或者函數(shù)起作用)
預(yù)解釋:
1,發(fā)現(xiàn)重復(fù)的,不重復(fù)聲明,只定義,重復(fù)定義只會(huì)替換之前的值;(函數(shù)聲明加定義一起完成)
2,預(yù)解釋不管條件;(在最新的瀏覽器(IE11及以上),不管條件成立與否都會(huì)提前聲明,不會(huì)提前定義,然后再看條件是否成立,如果成立則看有沒有函數(shù),如果有函數(shù),則先定義,如果沒有,JS代碼從上到下執(zhí)行成立的代碼。如果不成立,則走不成立的代碼)IE10及以下(不管條件是否成立函數(shù)都會(huì)進(jìn)行聲明+定義);
3,只對(duì)等號(hào)左邊的進(jìn)行變量提升,右邊是值,不會(huì)提前聲明什么的;
4,預(yù)解釋發(fā)生在同一個(gè)腳本塊中。
5,return 后面跟著的是值,不會(huì)進(jìn)行預(yù)解釋,但是return下面的代碼要進(jìn)行預(yù)解釋;
所有聲明變量或聲明函數(shù)都會(huì)被提升到當(dāng)前函數(shù)的頂部。
作用域鏈
在私有作用域中
聲明的變量和函數(shù)的形參都是私有的變量;
在私有作用域中,代碼執(zhí)行的時(shí)候遇到一個(gè)變量,首先看它是否為私有變量:
[是私有變量]
- 則和外面沒有任何關(guān)系,以后在這個(gè)作用域中操作的當(dāng)前變量都按照私有的處理;
[不是私有變量]
- 則往當(dāng)前作用域的上級(jí)作用域進(jìn)行查找,如果上級(jí)作用域中有,我們操作的都是上級(jí)作用域的中的變量(假如我們在當(dāng)前作用域把值改了,相當(dāng)于把上級(jí)作用域中的這個(gè)值給修改了)。如果上級(jí)作用域也沒有,則繼續(xù)往上查找,一直照到window為止,這就是作用域鏈;
- 如果找到window下也沒有,分兩種情況:**
- 我們是獲取值:console.log(total);->報(bào)錯(cuò),下面代碼不再執(zhí)行
- 我們是設(shè)置值:total=100;->相當(dāng)于給window增加了一個(gè)屬性名叫total,屬性值為100;
如何查找函數(shù)的上級(jí)作用域?
<font color=red>看當(dāng)前函數(shù)是在哪個(gè)作用域下定義的,那么它的上級(jí)作用域就是誰,和函數(shù)在哪執(zhí)行沒有任何關(guān)系;<font>
只有函數(shù)執(zhí)行的時(shí)候會(huì)產(chǎn)生私有作用域;
console.log(x,y);//undefined undefined
var x=10,
y=20;
function fn() {
console.log(x,y);//undefined 20(為什么不是100而是20,因?yàn)橄乱恍械膟=100還沒有執(zhí)行 哈哈哈被騙了吧)!
var x=y=100;
console.log(x,y);//100 100
}
fn();
console.log(x,y);//10 100 為什么x是10而不是100,因?yàn)殚]包里的x=100外界無法拿到;
作用域是否銷毀
堆內(nèi)存
1.對(duì)象數(shù)據(jù)類型或者函數(shù)數(shù)據(jù)類型在定義的時(shí)候首先都會(huì)先開辟一個(gè)堆內(nèi)存,堆內(nèi)存有一個(gè)引用地址,如果有變量或者元素事件知道了這個(gè)地址,我們就說這個(gè)堆內(nèi)存被占用了,那么就要考慮這個(gè)堆內(nèi)存是否會(huì)銷毀;
棧內(nèi)存
全局作用域:
- 只有當(dāng)頁面關(guān)閉的時(shí)候全局作用域才會(huì)銷毀。
私有作用域
一般來說,函數(shù)體中的代碼執(zhí)行完成,形成的棧內(nèi)存會(huì)立即釋放(自執(zhí)行函數(shù)也不例外),當(dāng)然也有不釋放的。
- 當(dāng)私有作用域中的堆內(nèi)存的地址被作用域以外的東西占用了,那么當(dāng)前的這個(gè)作用域就不能被銷毀(下面為三種情況)
- 函數(shù)執(zhí)行形成一個(gè)私有作用域,如果私有作用域中的部分內(nèi)容被以外的變量占用了,當(dāng)前作用域不銷毀
如:函數(shù)返回了一個(gè)引用數(shù)據(jù)類型的值,而且在外面有一個(gè)變量接受了這個(gè)返回值,此時(shí)當(dāng)前作用域就不能銷毀,想要銷毀只需把外面的變量賦值為null,即解除占用即可;
如果返回的是一個(gè)基本數(shù)據(jù)類型的值,而且外面有一個(gè)變量接收,當(dāng)前私有作用域是否會(huì)銷毀?
會(huì)銷毀,因?yàn)榉祷匾脭?shù)據(jù)類型的值會(huì)在私有作用域中開辟一個(gè)堆內(nèi)存,而且這個(gè)堆內(nèi)存被外面的變量或元素元素事件占用著,所以這個(gè)堆內(nèi)存不銷毀,進(jìn)而導(dǎo)致這個(gè)堆內(nèi)存所在的私有作用域也不會(huì)銷毀。而基本數(shù)據(jù)類型值是直接把值拷貝一份給外面的變量,所以返回完成后,函數(shù)中的堆內(nèi)存沒有被占用,就會(huì)被銷毀掉,形成的私有作用域也會(huì)被銷毀掉;
- 在一個(gè)私有的作用域中給DOM元素的事件綁定方法,一般情況下我們的私有作用域都不銷毀
- 下述情況屬于不立即銷毀
函數(shù)執(zhí)行返回一個(gè)函數(shù)沒有被其他東西占用,但是還需要執(zhí)行一次,所以暫時(shí)不銷毀,當(dāng)返回的函數(shù)執(zhí)行完成后,瀏覽器會(huì)在空閑的時(shí)候把它銷毀了;
<font color=red>總結(jié):作用域是否銷毀就看兩步:
- 1、這個(gè)作用域是否產(chǎn)生了堆內(nèi)存
- 2、這個(gè)作用域產(chǎn)生的堆內(nèi)存是否被這個(gè)作用域以外的變量或事件占用了,如果被占用了,那么這個(gè)堆內(nèi)存不能被銷毀,進(jìn)而導(dǎo)致這個(gè)私有作用域也不能被銷毀。<font>
如果產(chǎn)生的堆內(nèi)存被自身作用域中的變量占用了,那么這個(gè)堆內(nèi)存會(huì)在被使用后銷毀,所在的私有作用域也會(huì)被銷毀
閉包
函數(shù)執(zhí)行會(huì)形成一個(gè)私有的作用域,保護(hù)私有變量不受外部影響,從外部拿不到里面的變量,此時(shí)我們可以理解為私有作用域把私有變量保護(hù)了起來,這種保護(hù)機(jī)制稱之為'閉包'。由方法運(yùn)行而產(chǎn)生的私有作用域就叫閉包,為了讓變量更安全。閉包是一種機(jī)制而不是某種形式;
閉包面試總結(jié):
閉包就是連接私有作用域和外部作用域之間的一座橋梁,它不僅能保護(hù)私有變量不受外界干擾,還能保存一些內(nèi)容,而且還能把私有作用域中的東西拿到外部使用。如果我想在外部使用閉包中的值怎么辦?
1.在閉包中設(shè)置返回值,在外部聲明一個(gè)變量接收。
2.把閉包中的值賦值給window的一個(gè)屬性。
閉包的作用
1.保護(hù)
形成私有作用域,保護(hù)里面的私有變量不受外界的干擾,真實(shí)項(xiàng)目中,我們利用這種保護(hù)機(jī)制,實(shí)現(xiàn)團(tuán)隊(duì)協(xié)作開發(fā)(避免了多人同一個(gè)命名,導(dǎo)致代碼沖突的問題)
- jQuery:常用的JS類庫,提供了很多項(xiàng)目中常用的方法(兼容所有瀏覽器)
- Zepto:小型JQ,專門為移動(dòng)端開發(fā)準(zhǔn)備的
//JQ代碼片段
(funciton(window)){
var jQuery=function(){
....
}
....
window.jQuery=window.$=jQuery;
}(window);
jQery()
$()
//Zepto代碼片段
var Zepto=(function(){
var Zepto=funciton(){
...
};
....
return Zepto;
})();
var $=Zepto
Zepto();
$();
真實(shí)項(xiàng)目中,我們利用這種保護(hù)機(jī)制,實(shí)現(xiàn)團(tuán)隊(duì)協(xié)作開發(fā)(避免了多人同一個(gè)命名,導(dǎo)致代碼沖突的問題)
//A
(funciton()){
//A寫的代碼
function fn(){
....
}
....
window.fn=fn;
}();
//B
(function(){
//B寫的代碼
funciton fn(){
...
};
//B想要調(diào)取A寫的fn
window.fn();
})();
2.保存
函數(shù)執(zhí)行形成一個(gè)私有作用域,函數(shù)執(zhí)行完成,形成的這個(gè)棧內(nèi)存一般情況都會(huì)自動(dòng)釋放
但是當(dāng)棧內(nèi)存中的內(nèi)容被棧內(nèi)存以外的其他東西(變量/元素的事件)占用了,那么這個(gè)棧內(nèi)存就不能被釋放掉,也就形成了不銷毀的私有作用域(里面的私有變量也不會(huì)銷毀);
應(yīng)用:高級(jí)單例模式;
i++與++i的區(qū)別:
i++,先拿原有的值和其他值運(yùn)算,運(yùn)算后再累加1;
++i,先累加1,再拿結(jié)果進(jìn)行運(yùn)算;
++i和i=i+1的區(qū)別
++i在拿到i的值的時(shí)候,會(huì)先用Number()轉(zhuǎn)化一下,然后再累加1,之后再運(yùn)算,而i=i+1不會(huì);
函數(shù)的中的this問題
當(dāng)前函數(shù)的執(zhí)行主體,
this指向是函數(shù)執(zhí)行時(shí)決定的 不是編寫代碼時(shí)指定。this的幾種情況:
全局中的this是window,我們都研究函數(shù)內(nèi)部的this的指向問題
在JS的非嚴(yán)格模式下
- 1.自執(zhí)行函數(shù)中的this都是window
- 2.給元素的某個(gè)事件綁定方法,當(dāng)事件觸發(fā)執(zhí)行對(duì)應(yīng)方法的時(shí)候,方法中的this一般都是當(dāng)前操作的元素本身(在IE6-8下DOM2級(jí)事件用attachEvent綁定方法時(shí),方法中的this是window,而不是當(dāng)前操作元素本身)
- 3.函數(shù)執(zhí)行前的主體
+ fn(); this為windows
+ obj.fn(); this為obj
- 4.ES6中箭頭函數(shù)中的this繼承宿主環(huán)境中的this:看方法在哪定義的,宿主環(huán)境就是誰,箭頭函數(shù)中的this就是宿主環(huán)境中的this;
var obj={
fn:function(){
//=>this:obj
setTimeout(function(){
//=>this:window 不管在哪執(zhí)行,定時(shí)器中的this是window
},1000);
//=>想讓定時(shí)器函數(shù)中的this也是obj
setTimeout(function(){
//=>this:obj
}.bind(this),1000);
var _this=this;
setTimeout(function(){
//=>_this:obj
_this.name
='xxx';
},1000);
setTimeout(()=>{
//=>this:obj 箭頭函數(shù)中的this繼承宿主環(huán)境(上級(jí)作用域中)的this
},1000);
}
};
obj.fn();
在JS嚴(yán)格模式下(讓JS更加嚴(yán)謹(jǐn))
開啟嚴(yán)格模式:在當(dāng)前作用域的第一行加 "use strict"。開啟后所有作用域下再執(zhí)行的JS代碼都按照嚴(yán)格模式處理
- 嚴(yán)格模式下,沒有寫執(zhí)行主體的話,this就是undefined;
arguments實(shí)參集合(只有傳遞了實(shí)參才會(huì)保持映射,不傳遞一直都是undefined)
當(dāng)我們不知道用戶具體要傳遞幾個(gè)值得時(shí)候(傳遞幾個(gè)值都可以),此時(shí)我們無法設(shè)置形參的個(gè)數(shù);遇到此種情況,需要使用函數(shù)內(nèi)置的實(shí)參集合:arguments
1.arguments只有函數(shù)才有,是一個(gè)類數(shù)組集合
- 1、以數(shù)字作為索引(屬性名),從零開始
- 2、有一個(gè)length屬性,存儲(chǔ)的是當(dāng)前實(shí)參的個(gè)數(shù) arguments.length
- 3、arguments.callee 動(dòng)態(tài)的得到當(dāng)前執(zhí)行函數(shù)的方法名
2.不管執(zhí)行函數(shù)是否傳遞參數(shù),arguments天生就存在,沒有傳遞參數(shù)時(shí)arg是個(gè)空的集合,傳遞了參數(shù)的arg中包含了所有傳遞的參數(shù)信息,
如果沒有傳遞實(shí)參,那么形參的值在arguments中就是undefined如果有變量名與形參沖突,那么操作的一直都是私有變量,argument中沒有傳遞實(shí)參的形參的值還是undefined
var a=12,b=13,c=14;
~function(a,b){
//b沒有傳遞實(shí)參所以在arguments中的值一直都是undefined
b=b||0;
arguments[0]=100;
var b=c=200;
console.log(a);
console.log(arguments[1]);//undefined
}(a);
console.log(a);
console.log(b);
console.log(c);
<font color=red>非嚴(yán)格模式下,如果傳遞的有實(shí)參,那么arguments的值永遠(yuǎn)和對(duì)應(yīng)命名參數(shù)的值保持同步,如果沒有傳遞實(shí)參,則arguments中形參對(duì)應(yīng)的值就一直是undefined(來自高程3第66頁,在嚴(yán)格模式下arguments將不與實(shí)參保持映射關(guān)系。重寫arguments 的值會(huì)導(dǎo)致語法錯(cuò)誤(代碼將不會(huì)執(zhí)行)),但是如果使用delete 刪除了arguments中某一個(gè)索引對(duì)應(yīng)的值,再去修改實(shí)參,那么實(shí)參和arguments將不再保持同步;<font>
(function (a) {
delete arguments[0];
a=1;
console.log(a);//1
console.log(arguments);
//[empty × 1, callee: ?, Symbol(Symbol.iterator): ?]
// callee:? (a)
// length:1
// Symbol(Symbol.iterator):? values()
// __proto__:Object
})(2);
JS中函數(shù)的返回值return
函數(shù)中是有返回值的,我們?nèi)绻朐谕饷媸褂煤瘮?shù)私有的一些信息,那么就需要通過return,把這些信息返回出來供外面使用。如果不寫return或者return后面什么都不寫,則默認(rèn)返回undefined。函數(shù)體中,return后面的代碼不再執(zhí)行
return后面跟著的都是值:
function sum(){
var val=0;
return val;//返回的不是val變量,而是val所存儲(chǔ)的值
}
sum //代表函數(shù)本身
sum() //函數(shù)執(zhí)行,代表的是當(dāng)前函數(shù)執(zhí)行后返回的結(jié)果(return后面是什么函數(shù)返回的就是什么)
JS中的匿名函數(shù)(沒有名字的函數(shù))
函數(shù)表達(dá)式—>把一個(gè)匿名函數(shù)(有名字也可以)作為值賦值給一個(gè)變量或者一個(gè)元素的某個(gè)事件)
- 聲明的變量指向函數(shù)體時(shí)(即函數(shù)表達(dá)式),變量的聲明會(huì)被提升(foo的聲明會(huì)被提升),但是它指向的函數(shù)體只會(huì)在執(zhí)行的時(shí)候才被賦值。對(duì)于 var bar = function foo(){};語句,其實(shí)就是一個(gè)有效的命名函數(shù)表達(dá)式,但有一點(diǎn)需要記住:命名函數(shù)表達(dá)式的標(biāo)示符(即函數(shù)名稱)在外部作用域是無效的,在其內(nèi)部作用域是有效的。
自執(zhí)行函數(shù)—>創(chuàng)建函數(shù)和執(zhí)行函數(shù)放在一起了,創(chuàng)建完成后立馬執(zhí)行;(自執(zhí)行函數(shù)什么時(shí)候執(zhí)行?預(yù)解釋之后,JS代碼從上到下執(zhí)行,碰到自執(zhí)行函數(shù)時(shí),才會(huì)創(chuàng)建和執(zhí)行;)
以下都是自執(zhí)行函數(shù),符號(hào)只是控制語法規(guī)范
除了第一種,其他4中方式都會(huì)改變自執(zhí)行函數(shù)的返回結(jié)果
- (function(){})();
- ~function(n){}(10); ~:按位非,執(zhí)行按位非的結(jié)果就是返回?cái)?shù)值的反碼
- -function(n){}(10);
- +function(n){}(10);
- !function(n){}(10);
14、JS中操作DOM的屬性和方法
<font color=red>操作真實(shí)的DOM結(jié)構(gòu)是比較消耗性能的(盡量減少)</font>
DOM的映射機(jī)制
瀏覽器在渲染頁面的時(shí)候,給每一個(gè)元素都設(shè)置很多內(nèi)置的屬性(包含樣式的),當(dāng)我們在JS中把堆內(nèi)存中的某些東西修改了,大部分情況下,瀏覽器都會(huì)檢測到你的修改,按照最新的修改的值重新渲染頁面中的元素。
DOM的重繪和回流
重繪(repaint)針對(duì)某一個(gè)元素
當(dāng)元素的樣式發(fā)生改變(不修改元素位置的樣式),瀏覽器會(huì)把當(dāng)前元素重新的進(jìn)行渲染(DOM性能消耗低)
觸發(fā)重繪的場景:
- color的修改
- text-decoration的修改
- background的修改
- a:hover也會(huì)造成重繪
- :hover引起的顏色等不導(dǎo)致回流的style變動(dòng)
回流(reflow)針對(duì)整個(gè)頁面
當(dāng)元素的位置發(fā)生改變,瀏覽器會(huì)把整個(gè)頁面的DOM結(jié)構(gòu)進(jìn)行重新計(jì)算,計(jì)算出所有元素的最新位置,然后再渲染(DOM性能消耗非常大)
- 1、width/height/border/margin/padding的修改
- 2、動(dòng)畫,:hover等偽類引起的元素表現(xiàn)改動(dòng),display=none等造成頁面回流
- 3、appendChild等DOM元素操作
- 4、font類style的修改
- 5、background的修改,部分background的修改只觸發(fā)重繪,IE不用考慮
- 6、scroll頁面,不可避免
- 7、resize頁面,桌面版本進(jìn)行瀏覽器大小的縮放。
- 8、讀取元素屬性(offsetLeft、offsetTop、offsetHeight、offsetWidth、scrollTop/Left/Width/Height、clientTop/Left/Width/Height、getComputedStyle()、currentStyle(in IE));
如何解決重繪和回流
如何避免:
盡可能在 DOM 末梢通過改變 class 來修改元素的 style 屬性:盡可能的減少受影響的 DOM 元素。
避免設(shè)置多項(xiàng)內(nèi)聯(lián)樣式:使用常用的 class 的方式進(jìn)行設(shè)置樣式,以避免設(shè)置樣式時(shí)訪問 DOM 的低效率。
設(shè)置動(dòng)畫元素 position 屬性為 fixed 或者 absolute:由于當(dāng)前元素從 DOM 流中獨(dú)立出來,因此受影響的只有當(dāng)前元素,元素 repaint。
犧牲平滑度滿足性能:動(dòng)畫精度太強(qiáng),會(huì)造成更多次的 repaint/reflow,犧牲精度,能滿足性能的損耗,獲取性能和平滑度的平衡。
避免使用 table 進(jìn)行布局:table 的每個(gè)元素的大小以及內(nèi)容的改動(dòng),都會(huì)導(dǎo)致整個(gè) table 進(jìn)行重新計(jì)算,造成大幅度的 repaint 或者 reflow。改用 div 則可以進(jìn)行針對(duì)性的 repaint 和避免不必要的 reflow。
避免在 CSS 中使用運(yùn)算式:學(xué)習(xí) CSS 的時(shí)候就知道,這個(gè)應(yīng)該避免,不應(yīng)該加深到這一層再去了解,因?yàn)檫@個(gè)的后果確實(shí)非常嚴(yán)重,一旦存在動(dòng)畫性的 repaint/reflow,那么每一幀動(dòng)畫都會(huì)進(jìn)行計(jì)算,性能消耗不容小覷。
獲取節(jié)點(diǎn)
<font color=red>document.getElementById()</font>
在文檔中通過元素的ID名來獲取一個(gè)元素,只能通過document對(duì)象來調(diào)用,document屬于Document類的一個(gè)實(shí)例,只有在Document類的原型上才有g(shù)etElementById這個(gè)方法。
我們把document稱之為上下文(context):上文和下文,也就是獲取元素時(shí)候限制的那個(gè)范圍。
獲取的結(jié)果是一個(gè)對(duì)象數(shù)據(jù)類型的值,在JS中使用DOM提供的方法,獲取的元素都是對(duì)象,所以我們把獲取的結(jié)果稱之為 ‘元素對(duì)象’。
1.如果頁面中的ID重復(fù)了,我們獲取的結(jié)果是ID對(duì)應(yīng)的第一個(gè)元素對(duì)象
2.在IE7及以下會(huì)把表單元素中的name屬性值當(dāng)做ID來使用;而且會(huì)忽略ID的大小寫(項(xiàng)目中盡量不要讓表單的name和其他元素的id相同)
3.我們?nèi)绻袹S放在結(jié)構(gòu)下面,我們可以直接使用ID值來獲取這個(gè)元素(不需要通過getElementById來獲?。@種方式會(huì)把頁面中所有ID為同一個(gè)的都獲取到(只有一個(gè)的話獲取的是元素對(duì)象,多個(gè)的話獲取的是類數(shù)組集合)=>不推薦
<font color=red>注意:不要讓表單元素的name屬性值和其他元素的id重復(fù)、不要用id的大小寫來區(qū)分不同的元素</font>
不通過直接操作ID值的方式如何獲取多個(gè)相同ID的元素?
var allList=document.getElementsByTagName('*');
var ary=[];
for(var i=0;i<allList.length;i++){
allList[i].id===xxx?ary.push(allList[i]):null
}
return ary;
<font color=red>context.getElementsByTagName():</font>
在指定上下文中通過元素的標(biāo)簽名來獲取子子孫孫元素中的一組元素,獲取到的元素是類數(shù)組集合,通過索引來調(diào)用某一個(gè)
1、以數(shù)字作為屬性名,每一個(gè)屬性存儲(chǔ)的都是獲取到的每一個(gè)li,JS中我們把數(shù)字屬性名叫做“索引”(索引是逐級(jí)遞增的)
2、有一個(gè)length屬性存儲(chǔ)的是當(dāng)前集合中LI的個(gè)數(shù)
具備以上的兩個(gè)特點(diǎn)特別像數(shù)組,但是,它不是數(shù)組,所以我們把他稱之為“類數(shù)組”
<font color=red>document.getElementsByName():
</font>在指定上下文中通過元素的name屬性來獲取一組元素(類數(shù)組:節(jié)點(diǎn)集合 NodeList)
在IE瀏覽器下只對(duì)表單元素起作用
這個(gè)方法應(yīng)用于獲取具有同樣name 的表單元素
<font color=red>context.getElementsByClassName():
</font>通過元素的樣式類名來獲?。╟lass值)一組元素,獲取的也是一個(gè)類數(shù)組集合,通過索引來調(diào)用某一個(gè);
getElementsByClassName()是項(xiàng)目中最常用的一種方法,但是這個(gè)方法在IE6-8下不兼容
<font color=red>document.documentElement:</font>獲取HTML元素
<font color=red>document.body:</font>獲取body元素
在移動(dòng)端獲取元素常用的方法(IE6-8下不兼容)
documetn.querySelector():
獲取一個(gè)
document.querySelectorAll():
獲取多個(gè) 類數(shù)組集合(獲取到的元素集合或節(jié)點(diǎn)集合不存在DOM映射,因?yàn)楂@取到的集合不是標(biāo)準(zhǔn)的NodeList,而是屬于StaticNodeList(靜態(tài)集合))
document.querySelector("#tab");ID選擇器
document.querySelectorAll("#tab li ");//層級(jí)選擇器
document.querySelectorAll("input[type='radio']");//過慮選擇器
className:
通過這個(gè)屬性可以獲取或者設(shè)置當(dāng)前元素對(duì)象的樣式類
innerHTML:
通過這個(gè)屬性可以獲取或者設(shè)置元素里面的內(nèi)容
innerText:
通過這個(gè)屬性可以設(shè)置或者獲取元素里面的文本內(nèi)容
火狐中不支持innerText屬性,我們用textContent代替innerText
<font color=red>innerHTML與innerText的區(qū)別:</font>
- innerHTML可以把增加內(nèi)容中的HTML標(biāo)簽進(jìn)行識(shí)別,innerText只能設(shè)置或者獲取文本內(nèi)容,不能識(shí)別HTML標(biāo)簽,HTML標(biāo)簽會(huì)被當(dāng)作文本處理
style屬性:
通過這個(gè)屬性我們可以獲取或者設(shè)置元素的樣式(只能是元素的行內(nèi)樣式,獲取或者設(shè)置都是,寫在內(nèi)嵌或者外鏈中的css樣式無法獲取到)
window.getComputStyle(元素,偽類)[屬性值] || 元素.currentStyle[屬性值]:
獲取當(dāng)前元素經(jīng)過瀏覽器計(jì)算的屬性值,不管是寫在哪的;
獲取關(guān)系的屬性
childNodes:獲取所有的子節(jié)點(diǎn)
獲取當(dāng)前元素的所有子節(jié)點(diǎn)(節(jié)點(diǎn)集合:類數(shù)組)
注:不僅是元素子節(jié)點(diǎn),文本、注釋等都會(huì)包含在內(nèi);子節(jié)點(diǎn)說明只是在兒子輩分中查找;
childredn:獲取所有的元素子節(jié)點(diǎn)
獲取所有的元素子節(jié)點(diǎn)(元素集合)
在IE6-8下獲取的結(jié)果和標(biāo)準(zhǔn)瀏覽器中有區(qū)別:會(huì)把注釋節(jié)點(diǎn)當(dāng)作元素節(jié)點(diǎn)獲取到
parentNode:獲取元素的父親節(jié)點(diǎn)(元素對(duì)象)
previousSibling:獲取哥哥節(jié)點(diǎn)(包括文本或注釋)
nextSibling:獲取弟弟節(jié)點(diǎn)(包括文本或注釋)
IE6-8下不兼容
previousElementSibling:獲取上一個(gè)元素節(jié)點(diǎn)
nextElementSibling:獲取下一個(gè)元素節(jié)點(diǎn)
firstChild:獲取所有子節(jié)點(diǎn)中的第一個(gè)
lastChild:獲取所有子節(jié)點(diǎn)的最后一個(gè)
firstElementChild/lastElementChild IE6-8下不兼容
節(jié)點(diǎn)類型
節(jié)點(diǎn)類型 nodeType nodeName nodeValue 元素節(jié)點(diǎn) 1 大寫的標(biāo)簽名 null 屬性節(jié)點(diǎn) 2 大寫的屬性名 屬性值 文本節(jié)點(diǎn) 3 #text 文字內(nèi)容 注釋節(jié)點(diǎn) 8 #comment 注釋內(nèi)容 document 9 #document null 在標(biāo)準(zhǔn)瀏覽器下,我們把空格和回車都當(dāng)成文本節(jié)點(diǎn)處理
ele.tagName:獲取當(dāng)前元素的標(biāo)簽名(獲取的一般都是大寫),tagName只有元素節(jié)點(diǎn)才有;
節(jié)點(diǎn)操作
創(chuàng)建節(jié)點(diǎn)
document.createElement(元素標(biāo)簽):動(dòng)態(tài)創(chuàng)建一個(gè)元素節(jié)點(diǎn)
document.createAttribute(元素屬性):動(dòng)態(tài)創(chuàng)建一個(gè)屬性節(jié)點(diǎn)
document.createTextNode(文本內(nèi)容):動(dòng)態(tài)創(chuàng)建一個(gè)文本節(jié)點(diǎn)
插入節(jié)點(diǎn)
appendChild():把元素添加到指定容器的末尾位置
容器.appendChild(元素)
insertBefore(a,b):把新的元素a,添加到老的元素b之前
容器.insertBefore(a,b)
替換節(jié)點(diǎn)
replaceChild(a,b):用a元素來替換容器中的b元素
容器.replcaeChild(a,b);
復(fù)制節(jié)點(diǎn)
cloneNode(true/false):克隆元素節(jié)點(diǎn),true表示包括所有子節(jié)點(diǎn),默認(rèn)為false
要克隆的元素.cloneNode(),無法克隆元素綁定的事件
刪除節(jié)點(diǎn)
removerChild():從容器中刪除指定元素
容器.removeChild(元素)
屬性操作
獲取屬性
getAttribute(元素屬性名):獲取元素節(jié)點(diǎn)中指定屬性的屬性值
元素節(jié)點(diǎn).getAttribute(元素屬性名)
設(shè)置屬性
setAttribute(元素屬性名):設(shè)置或者改變元素節(jié)點(diǎn)的屬性值(一般都是操作自定義屬性)
元素節(jié)點(diǎn).setAttribute(屬性名,屬性值),可以設(shè)置自定義的屬性,會(huì)修改html結(jié)構(gòu),直接在html中體現(xiàn)出來。用setAttribute設(shè)置的只能用getAttribute來獲取,只能用removeAttribute來刪除
注意:在IE6-8下無法修改和設(shè)置class屬性
刪除屬性
removeAttribute(元素屬性名):刪除元素節(jié)點(diǎn)的屬性
元素節(jié)點(diǎn).removeAttribute(屬性名)
設(shè)置或者獲取自定義屬性有xxx.屬性名=屬性值和 xxx.setAttribute(元素屬性名)兩種方式,有以下區(qū)別:
1,xxx.屬性名 結(jié)果體現(xiàn)在對(duì)象的屬性上。與HTML結(jié)構(gòu)無關(guān)。
1,xxx.setAttribute(屬性名) 結(jié)果體現(xiàn)在DOM結(jié)構(gòu)上,即在HTML結(jié)構(gòu)中可以看到;
如果使用DOM的內(nèi)置屬性操作元素,那么元素就會(huì)被當(dāng)作特殊對(duì)象,和HTML結(jié)構(gòu)產(chǎn)生映射關(guān)系(即結(jié)果會(huì)呈現(xiàn)在HTML結(jié)構(gòu)上)