js基礎(chǔ)(3)

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下也沒有,分兩種情況:**
    1. 我們是獲取值:console.log(total);->報(bào)錯(cuò),下面代碼不再執(zhí)行
    1. 我們是設(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)上)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第3章 基本概念 3.1 語法 3.2 關(guān)鍵字和保留字 3.3 變量 3.4 數(shù)據(jù)類型 5種簡單數(shù)據(jù)類型:Unde...
    RickCole閱讀 5,488評(píng)論 0 21
  • 〇、前言 本文共108張圖,流量黨請慎重! 歷時(shí)1個(gè)半月,我把自己學(xué)習(xí)Python基礎(chǔ)知識(shí)的框架詳細(xì)梳理了一遍。 ...
    Raxxie閱讀 19,556評(píng)論 17 410
  • 二十多年前,我那個(gè)在方圓幾里頗具威望的小奶奶還活著。 每到逢年過節(jié),她家的客廳就成了如假包換的女子沙龍:清一色的七...
    東周魚閱讀 761評(píng)論 0 1
  • 用四天時(shí)間讀完完美健康,百年孤獨(dú),瓦爾登湖,和穆斯林的葬禮。 這是這個(gè)月最大的收獲了。 劇本還在寫,大綱交了四個(gè)。...
    Wendyzhen閱讀 224評(píng)論 0 0
  • 小時(shí)候最喜歡的事無過于摘桑椹了。 桑樹分成2種,一種叫苦桑,葉子小而老,桑葚小而干,是最原始的品種,基本都是廢材,...
    閑人不二閱讀 443評(píng)論 3 2

友情鏈接更多精彩內(nèi)容