成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript 面向?qū)ο箝_發(fā)知識(shí)總結(jié)基礎(chǔ)篇

Kross / 2839人閱讀

摘要:字面形式允許你在不需要使用操作符和構(gòu)造函數(shù)顯式創(chuàng)建對(duì)象的情況下生成引用值。操作符以一個(gè)對(duì)象和一個(gè)構(gòu)造函數(shù)作為參數(shù)鑒別數(shù)組有前一小結(jié)可以知道鑒別數(shù)組類型可以使用。屬性是函數(shù)獨(dú)有的,表明該對(duì)象可以被執(zhí)行。這種函數(shù)被稱為匿名函數(shù)。

引子:

1.JavaScript 中的變量類型和類型檢測(cè)

1.1原始類型

1.2引用類型

1.3內(nèi)建類型的實(shí)例化

1.4函數(shù)的字面形式

1.5正則表達(dá)式的字面形式

1.6類型檢測(cè)

1.6.1原始類型的檢測(cè)

1.6.2鑒別引用類型

1.6.3鑒別數(shù)組

1.6.4原始封裝類型

2.JavaScript 中的函數(shù)

2.1定義函數(shù)的兩種方式

2.1.1函數(shù)聲明

2.1.2函數(shù)表達(dá)式

2.2JavaScript函數(shù)的參數(shù)

2.3函數(shù)的重載

2.4函數(shù)使用最重要的3個(gè)點(diǎn)

2.4.1 this的使用

2.4.2 call和apply的使用

2.4.3 bind的使用

引子:

最近看了兩本書,書中有些內(nèi)容對(duì)自己還是很新的,有些內(nèi)容是之前自己理解不夠深的,所以拿出來總結(jié)一下,這兩本書的名字如下:

JavaScript 面向?qū)ο缶?/p>

JavaScript 啟示錄

如果對(duì)于 JavaScript 面向?qū)ο缶幊汤斫獠粔蛏畹脑?,第一本書還是強(qiáng)烈推薦的。第二本書比較適合初中級(jí)的開發(fā)者閱讀。對(duì)各種知識(shí)點(diǎn)都有代碼示例。內(nèi)容中規(guī)中矩。

1.JavaScript 中的變量類型和類型檢測(cè)

C#和Java等編程語言用棧存儲(chǔ)原始類型,用堆存儲(chǔ)引用類型,JavaScript則完全不同:它使用一個(gè)變量對(duì)象追蹤變量的生存期。原始值被直接保存在變量對(duì)象內(nèi),而引用值則作為一個(gè)指針保存在變量對(duì)象內(nèi),該指針指向?qū)嶋H對(duì)象在內(nèi)存中的存儲(chǔ)位置。

1.1原始類型

在 JavaScript 中有5中原始類型,分別如下:

類型表達(dá)式 類型描述
boolean 布爾,值為 false或者 true
number 數(shù)字,值為任何整型或者浮點(diǎn)數(shù)值
string 字符串,值由單引號(hào)或者雙引號(hào)括出的單個(gè)字符或者連續(xù)字符(JavaScript不區(qū)分字符類型)
null 空類型,該原始類型僅有一個(gè)值:null
undefined 未定義,該原始類型僅有一個(gè)值:undefined(undefined會(huì)被賦給一個(gè)還沒有初始化的變量)

所有原始類型的值都有字面形式,字面形式是不被保存在變量中的值。

//string

var name="zhiqiang";
var selection="a";

//number

var count=235;
var cost=1.51;

//boolean

var found=true;

//null

var object=null;

//undefined

var flag=undefined;
var ref;

console.log(ref);  //undefined

原始類型的變量直接保存原始值(而不是一個(gè)指向?qū)ο蟮闹羔槪?。?dāng)將原始值賦值給一個(gè)變量時(shí),該值將被復(fù)制到變量中。也就是說,如果你使一個(gè)變量等于另一個(gè)時(shí),每個(gè)變量有它自己的一份數(shù)據(jù)拷貝。

示例代碼如下:

var color1="red";
var color2=color1;

內(nèi)存中的保存形式,如下圖:

1.2引用類型

引用類型是在JavaScript中找到最能接近類的東西。引用值是引用類型的實(shí)例,也是對(duì)象的同義詞。屬性包含鍵(始終是字符串)和值。如果一個(gè)屬性的值是函數(shù),它就被稱為方法。JavaScript中函數(shù)其實(shí)是引用值,除了函數(shù)可以運(yùn)行以外,一個(gè)包含數(shù)組的屬性和一個(gè)包含函數(shù)的屬性沒有區(qū)別。

創(chuàng)建引用類型的兩種方式看下面的一段代碼:

//第一種使用new操作符
var obj1 = new Object();  //
var obj2 = obj1;

//第二種
var obj3 = {}

以上兩種創(chuàng)建對(duì)象的方式并沒有本質(zhì)的區(qū)別,是等價(jià)的。

那么當(dāng)我們創(chuàng)建了一個(gè)對(duì)象,且發(fā)生了賦值的時(shí)候,在內(nèi)存中發(fā)生了什么呢?

看下圖:

1.當(dāng)發(fā)生了new操作的時(shí)候,先在內(nèi)存中開辟一塊空間,存放創(chuàng)建的對(duì)象,并且使obj1指向這塊開辟的空間;

2.引用類型發(fā)生賦值的時(shí)候,僅僅是引用地址指向了內(nèi)存中的同一塊區(qū)域;

JavaScript語言有"垃圾回收"功能,所以在使用引用類型的時(shí)候無需擔(dān)心內(nèi)存分配。但是為了防止"內(nèi)存泄露"還是應(yīng)該在不實(shí)用對(duì)象的時(shí)候?qū)⒃搶?duì)象的引用賦值為null。讓"垃圾回收"器在特定的時(shí)間對(duì)那一塊內(nèi)存進(jìn)行回收。

1.3內(nèi)建類型的實(shí)例化

JavaScript中的內(nèi)建類型如下:

類型 類型描述
Array 數(shù)組類型,以數(shù)字為索引的一組值的有序列表
Date 日期和時(shí)間類型
Error 運(yùn)行期錯(cuò)誤類型
Function 函數(shù)類型
Object 通用對(duì)象類型
RegExp 正則表達(dá)式類型

內(nèi)建引用類型有字面形式。字面形式允許你在不需要使用new操作符和構(gòu)造函數(shù)顯式創(chuàng)建對(duì)象的情況下生成引用值。(包括字符串,數(shù)字,布爾,空類型和未定義);

1.4函數(shù)的字面形式

創(chuàng)建函數(shù)的三種方式:

//第一種函數(shù)聲明
function abc(){
    console.log(1);
}

//使用構(gòu)造函數(shù)的形式
var value = new Function("","console.log(1)");

//函數(shù)表達(dá)式
var a = function(){
    console.log(1);
};

使用構(gòu)造函數(shù)的方式創(chuàng)建函數(shù),不易讀,且調(diào)試不方便,不建議使用這種方式創(chuàng)建函數(shù)。

1.5正則表達(dá)式的字面形式

在JavaScript中使用正則表達(dá)式有兩種方式:

var a1 = /d+/g;//使用字面形式
var a2 = new RegExp("d+","g");//使用構(gòu)造函數(shù)的形式

在JavaScript中建議使用字面形式的正則表達(dá)式,因?yàn)椴恍枰獡?dān)心字符串中的轉(zhuǎn)義字符。比如上面示例代碼中字面形式使用d而構(gòu)造函數(shù)使用的是d;

1.6類型檢測(cè) 1.6.1原始類型的檢測(cè)

使用typeof運(yùn)算符可以完成對(duì)原始類型的檢測(cè),看下面的一段代碼:

上面的代碼中有一段比較特殊就是

typeof null   //object

這里其實(shí)是不準(zhǔn)確的,如果我們要判斷一個(gè)值是否為空類型的最佳的方式是直接和null進(jìn)行比較

console.log(value === null);

=====之間的最主要的區(qū)別就是前者在進(jìn)行比較的時(shí)候會(huì)進(jìn)行類型轉(zhuǎn)化,而后者不會(huì);

console.log(5==5);//true
console.log("5"==5);//false
console.log("5"===5);//fasle
1.6.2鑒別引用類型

JavaScript中對(duì)于引用類型的檢測(cè)較為復(fù)雜。對(duì)于函數(shù)類型的引用使用typeof返回的是Function,而對(duì)于非函數(shù)的引用類型返回的則是object。所以在JavaScript中鑒別引用類型的類型引入了instanceof。

instanceof操作符以一個(gè)對(duì)象和一個(gè)構(gòu)造函數(shù)作為參數(shù);

function a (){}
var b = {};
var c =[];

typeof a   // function
typeof b  //object
typeof c //object

a instanceof Function //true
b instanceof Object  //true
c instanceof Array   //true
1.6.3鑒別數(shù)組

有前一小結(jié)可以知道鑒別數(shù)組類型可以使用instanceof。但是在ECMAScript5中,Array對(duì)象提供了更好的方式來鑒別一個(gè)變量是不是數(shù)組類型。

var a = [];
var b =3;
Array.isArray(a);  //true
Array.isArray(b); //false

注意:IE8及更早的IE不支持該方法

1.6.4原始封裝類型

JavaScript中的原始封裝類型共有3種。這些特殊引用類型的存在使得原始類型用起來和對(duì)象一樣方便。當(dāng)讀取字符串,數(shù)字,布爾類型時(shí),原始封裝類型被自動(dòng)創(chuàng)建。

var a ="qwer";
var firstChar = a.chatAt(0);
console.log(firstChar);//  q

在JavaScript引擎中發(fā)生了如下的過程:

var a ="qwer";
var temp = new String(a);
var firstChar = temp.chatAt(0);
temp =null;
console.log(firstChar);//  q

由于要把字符串當(dāng)成對(duì)象使用,JavaScript引擎創(chuàng)建了一個(gè)字符串實(shí)體讓charAt可以工作,字符串對(duì)象(temp)的存在僅僅用于該語句(temp.chatAt(0)),隨后便被銷毀(temp =null)。

我們可以簡(jiǎn)單測(cè)試一下

var a ="qwer";
a.temp ="122";
console.log(a.temp);  //undefined

上面代碼的過程如下:

var a ="qwer";
var temp = new String(a);
temp.temp ="122";
temp=null;

var temp = new String(a);
console.log(a.temp);  //undefined
temp=null;

由上面的代碼我們可以看到我們實(shí)際上是在一個(gè)立刻就會(huì)被銷毀的對(duì)象上而不是字符串上添加了一個(gè)新屬性。當(dāng)試圖訪問這個(gè)屬性時(shí),另一個(gè)不同的臨時(shí)對(duì)象被創(chuàng)建,而新屬性并不存在。雖然原始封裝類型會(huì)被自動(dòng)創(chuàng)建,但是在這些值上進(jìn)行instanceof檢查對(duì)應(yīng)類型的返回值卻都是false;

var a ="1234";
var num = 10;

a instanceof String //false
num instanceof Number //false

這是因?yàn)榕R時(shí)對(duì)象僅在值被讀取的時(shí)候創(chuàng)建,隨即被銷毀。instanceof操作符并沒有讀取到任何東西,也沒有臨時(shí)對(duì)象的創(chuàng)建,因此它告訴我們這些值并不屬于原始封裝類型;

但是我們可以手動(dòng)創(chuàng)建原始封裝類型,但是此時(shí)使用typeof沒辦法檢測(cè)對(duì)象的實(shí)際類型,只能夠使用instanceof來檢測(cè)變量類型;

2.JavaScript 中的函數(shù)

在JavaScript中函數(shù)就是對(duì)象。函數(shù)不同于其他對(duì)象的決定性特點(diǎn)是,函數(shù)存在一個(gè)被稱為[[Call]]的內(nèi)部屬性。內(nèi)部屬性無法通過代碼訪問而是定義了代碼執(zhí)行時(shí)的行為。ECMAScript為JavaScript的對(duì)象定義了多種內(nèi)部屬性,這些內(nèi)部屬性都用雙重中括號(hào)來標(biāo)注。

[[Call]]屬性是函數(shù)獨(dú)有的,表明該對(duì)象可以被執(zhí)行。由于僅函數(shù)擁有該屬性,ECMAScript定義了typeof操作符對(duì)任何具有[[Call]]屬性的對(duì)象返回**function**>

2.1定義函數(shù)的兩種方式 2.1.1函數(shù)聲明

函數(shù)聲明是以function關(guān)鍵字開頭,這也是區(qū)別函數(shù)聲明和函數(shù)表達(dá)式的一個(gè)重要的方法。函數(shù)聲明會(huì)在編譯期對(duì)整個(gè)作用域內(nèi)的變量名字進(jìn)行查詢,函數(shù)聲明的變量被提升至上下文的頂部,也就是說可以先使用函數(shù)后聲明它們。

abc();
function abc(){
    console.log(2);
}
2.1.2函數(shù)表達(dá)式

函數(shù)表達(dá)式是function關(guān)鍵字后邊不需要加上函數(shù)的名字。這種函數(shù)被稱為匿名函數(shù)。因?yàn)楹瘮?shù)對(duì)象本身沒有名字,所以函數(shù)表達(dá)式通常會(huì)被一個(gè)變量或者屬性引用。

abcd()
var abcd=function(){
    console.log(1)
};

var aaa={
    abc:function(){

    }
}

函數(shù)表達(dá)式只能通過變量引用,無法提升匿名函數(shù)的作用域。在使用函數(shù)表達(dá)式之前必須先創(chuàng)建它們,否則代碼會(huì)報(bào)錯(cuò)??词纠a的運(yùn)行結(jié)果:

2.2JavaScript函數(shù)的參數(shù)

JavaScript函數(shù)參數(shù)與很多語言函數(shù)參數(shù)不一樣。你可以給函數(shù)傳遞任意數(shù)量的參數(shù)卻不造成錯(cuò)誤。那是因?yàn)楹瘮?shù)實(shí)際上被保存在一個(gè)被稱為arguments的類似數(shù)組的對(duì)象中。arguments可以自由增長(zhǎng)來包含任意個(gè)數(shù)的值,這些值可以通過數(shù)字索引來引用。argumentslength屬性會(huì)告訴你目前有多少個(gè)值(函數(shù)接受了多少個(gè)參數(shù))。

arguments是一個(gè)類數(shù)組對(duì)象,它本身并不具有JavaScript數(shù)組應(yīng)該具有的全部的屬性和方法。

這里我們思考一個(gè)問題,我們?cè)趺磳⒁粋€(gè)類數(shù)組轉(zhuǎn)化為真正的數(shù)組?

最基本的我們應(yīng)該想到的是創(chuàng)建一個(gè)原始的空數(shù)組,使用for循環(huán)將類數(shù)組中的每一項(xiàng)添加到新的數(shù)組中;

如果使用Zepto或者jQuery的話,會(huì)有一個(gè)toArray()的方法可以使用;

ES6有Array.from(arrayLike[, mapFn[, thisArg]])可以將類數(shù)組轉(zhuǎn)化為數(shù)組對(duì)象;

最后一種也是最高級(jí)的一種方法就是使用原型的方式;

借用原型的方式把一個(gè)類數(shù)組轉(zhuǎn)化為真正的數(shù)組的示例代碼:

function abc(){
    console.log(arguments);
    var arrTemp = [].slice.apply(arguments);   //相當(dāng)于Array.prototype.slice == [].slice
    console.log(arrTemp);
    console.log(Array.isArray(arrTemp));
}

abc(1,2,3);

輸出結(jié)果:

2.3函數(shù)的重載

依稀的記得在學(xué)習(xí)的從C# 的時(shí)候,這些強(qiáng)類型語言對(duì)重載的定義:函數(shù)名相同,參數(shù)不同,或者是參數(shù)類型不同都可以叫做函數(shù)的重載。

但是在JavaScript這樣的語言中因?yàn)?arguments的存在,JavaScript的函數(shù)根本就不存在所謂的簽名,所以重載在JavaScript中實(shí)際是不存在的。

但是我們可以根據(jù)arguments傳入函數(shù)體的參數(shù)個(gè)數(shù)來模擬_函數(shù)重載_:

function abc(){
    if (arguments.length ===1){
        //A
    }
    if(arguments.length ===2){
        //B
    }
}

abc(11);
abc(11,22);

這里主要是滿足某些特殊場(chǎng)合的需求吧。

2.4函數(shù)使用最重要的3個(gè)點(diǎn)

this;

apply()和call();

bind();

關(guān)于thiscall,applybind這幾個(gè)概念在之前博客文章已經(jīng)介紹過很多遍了。在這里還是做一下簡(jiǎn)單的介紹。

2.4.1 this的使用

this的指向在函數(shù)定義的時(shí)候是確定不了的,只有函數(shù)執(zhí)行的時(shí)候才能確定this到底指向誰,實(shí)際上this的最終指向的是那個(gè)調(diào)用它的對(duì)象;

this指向的對(duì)象是在代碼的運(yùn)行期決定的。既上面說的,誰調(diào)用了它,就指向誰。一個(gè)很簡(jiǎn)單的總結(jié)就是,在函數(shù)中使用this,當(dāng)前this指向的是當(dāng)前window對(duì)象。在對(duì)象的方法中使用this,this指向的是當(dāng)前對(duì)象(這個(gè)也是最容易出錯(cuò)的地方)。

2.4.2 call和apply的使用

關(guān)于這兩個(gè)概念,之前的博客文章也介紹多很多次。這里也簡(jiǎn)單總結(jié)介紹一下。callapply主要是在執(zhí)行某個(gè)對(duì)象的方法的時(shí)候來改變當(dāng)前this的指向。主要用在對(duì)象繼承的時(shí)候。

2.4.3 bind的使用

bind也是改變對(duì)象this指向的一個(gè)方法。這個(gè)方法是ECMAScript5中新添加的一個(gè)方法。但是bindcall,apply的主要區(qū)別就是bind的第一個(gè)參數(shù)是要傳給新函數(shù)的this的值。其它所有參數(shù)代表需要被永久設(shè)置在新函數(shù)中的命名參數(shù)??梢栽谥罄^續(xù)設(shè)置任何非永久參數(shù)。

來看一段示例代碼:

function abc (lab){
    console.log(lab + this.name);
}

var person1 = {
    name:"xiaogang"
}

var person2={
    name:"zhiqiang21"
}

var sayNamePer1 =abc.bind(person1);
sayNamePer1("person1");


var sayNamePer2 =abc.bind(person2,"person2");
sayNamePer2();

person2.sayName = sayNamePer1;
person2.sayName("person2");

上面的代碼中:

sayNamePer1在綁定的時(shí)候沒有傳入?yún)?shù),所以仍需要后續(xù)執(zhí)行sayNamePer1來傳入lab參數(shù);sayNamePer2不僅綁定了thisperson2,還綁定了輸入的第一個(gè)參數(shù)是person2。意味著可以可以直接執(zhí)行sayNamePer2()。最后一個(gè)是將sayNamePer1設(shè)置位person2sayName方法。由于其this的值已經(jīng)綁定,所以雖然sayNamePer1person2的方法,但是輸出的仍然是person1.name的值。

其實(shí)總結(jié)一句話call,apply和bind的主要區(qū)別就是:

callapply是綁定既執(zhí)行。bind是有返回值的,先綁定后執(zhí)行。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/90892.html

相關(guān)文章

  • 【連載】前端個(gè)人文章整理-從基礎(chǔ)到入門

    摘要:個(gè)人前端文章整理從最開始萌生寫文章的想法,到著手開始寫,再到現(xiàn)在已經(jīng)一年的時(shí)間了,由于工作比較忙,更新緩慢,后面還是會(huì)繼更新,現(xiàn)將已經(jīng)寫好的文章整理一個(gè)目錄,方便更多的小伙伴去學(xué)習(xí)。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個(gè)人前端文章整理 從最開始萌生寫文章的想法,到著手...

    madthumb 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.40 - 2018,來學(xué)習(xí)一門新的編程語言吧!

    摘要:入門,第一個(gè)這是一門很新的語言,年前后正式公布,算起來是比較年輕的編程語言了,更重要的是它是面向程序員的函數(shù)式編程語言,它的代碼運(yùn)行在之上。它通過編輯類工具,帶來了先進(jìn)的編輯體驗(yàn),增強(qiáng)了語言服務(wù)。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不覺已經(jīng)到來了,總結(jié)過去的 2017,相信小伙們一定有很多收獲...

    caspar 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.40 - 2018,來學(xué)習(xí)一門新的編程語言吧!

    摘要:入門,第一個(gè)這是一門很新的語言,年前后正式公布,算起來是比較年輕的編程語言了,更重要的是它是面向程序員的函數(shù)式編程語言,它的代碼運(yùn)行在之上。它通過編輯類工具,帶來了先進(jìn)的編輯體驗(yàn),增強(qiáng)了語言服務(wù)。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不覺已經(jīng)到來了,總結(jié)過去的 2017,相信小伙們一定有很多收獲...

    nihao 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<