一、數組
1.1 數組的概念
- 數組可以把一組相關的數據一起存放,并提供方便的訪問(獲取)方式。
- 數組是指一組數據的集合,其中的每個數據被稱作元素,在數組中可以存放任意類型的元素。數組是一種將一組數據存儲在單個變量名下的優雅方式。
1.2 創建數組
-
利用數組字面量創建數組(常用方式)
//1. 使用數組字面量方式創建空的數組 var 數組名 = []; //2. 使用數組字面量方式創建帶初始值的數組 var 數組名 = ['小白','小黑','大黃','瑞奇'];
- 數組的字面量是方括號 [ ]
- 聲明數組并賦值稱為數組的初始化
- 這種字面量方式也是我們以后最多使用的方式
1.3 獲取數組中的元素
索引 (下標) :用來訪問數組元素的序號(數組下標從 0 開始)。
// 定義數組
var arrStus = [1,2,3];
// 獲取數組中的第2個元素
console.log(arrStus[1]); // 數字2
注意:如果訪問時數組沒有和索引值對應的元素,則得到的值是undefined
1.4 遍歷數組
-
數組遍歷
? 把數組中的每個元素從頭到尾都訪問一次(類似學生的點名),可以通過 for 循環索引遍歷數組中的每一項
var arr = ['red','green', 'blue'];
for(var i = 0; i < arr.length; i++){
console.log(arrStus[i]);
}
注意:
- 數組的長度是數組元素的個數 ,不要和數組的索引號混淆。
- length 屬性動態檢測數組元素的個數
- 數組的length屬性可以被修改:
(1)如果設置的length屬性值大于數組的元素個數,則會在數組末尾出現空白元素[undefined];
(2)如果設置的length屬性值小于數組的元素個數,則會把超過該值的數組元素刪除
1.5 數組中新增元素
?數組中可以通過以下方式在數組的末尾插入新元素:
數組[ 數組.length ] = 新數據;
翻轉數組
// 將數組 ['red', 'green', 'blue', 'pink', 'purple'] 的內容反過來存放
// 1、聲明一個新數組 newArr
// 2、把舊數組索引號第4個取過來(arr.length - 1),給新數組索引號第0個元素 (newArr.length)
// 3、我們采取 遞減的方式 i--
var arr = ['red', 'green', 'blue', 'pink', 'purple', 'hotpink'];
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i]
}
console.log(newArr);
1.6 冒泡排序
// var arr = [5, 4, 3, 2, 1];
var arr = [4, 1, 2, 3, 5];
for (var i = 0; i <= arr.length - 1; i++) { // 外層循環管趟數
for (var j = 0; j <= arr.length - i - 1; j++) { // 里面的循環管 每一趟的交換次數
// 內部交換2個變量的值 前一個和后面一個數組元素相比較
if (arr[j] < arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
二、函數
2.1 函數的概念
在 JS 里面,可能會定義非常多的相同代碼或者功能相似的代碼,這些代碼可能需要大量重復使用。雖然 for循環語句也能實現一些簡單的重復操作,但是比較具有局限性,此時我們就可以使用 JS 中的函數。
函數:就是封裝了一段可被重復調用執行的代碼塊。通過此代碼塊可以實現大量代碼的重復使用。
2.2 函數的使用
聲明函數
// 聲明函數
function 函數名() {
//函數體代碼
}
- function 是聲明函數的關鍵字,必須小寫
- 由于函數一般是為了實現某個功能才定義的, 所以通常我們將函數名命名為動詞,比如 getSum
調用函數
// 調用函數
函數名(); // 通過調用函數名來執行函數體代碼
- 調用的時候千萬不要忘記添加小括號
- 口訣:函數不調用,自己不執行
函數的封裝
函數的封裝是把一個或者多個功能通過函數的方式封裝起來,對外只提供一個簡單的函數接口
-
簡單理解:封裝類似于將電腦配件整合組裝到機箱中 ( 類似快遞打包)
2.3 函數的參數
函數參數語法
形參:函數定義時設置接收調用時傳入
實參:函數調用時傳入小括號內的真實數據
參數的作用 : 在函數內部某些值不能固定,我們可以通過參數在調用函數時傳遞不同的值進去。
函數參數的運用:
// 帶參數的函數聲明
function 函數名(形參1, 形參2 , 形參3...) { // 可以定義任意多的參數,用逗號分隔
// 函數體
}
// 帶參數的函數調用
函數名(實參1, 實參2, 實參3...);
- 調用的時候實參值是傳遞給形參的
- 形參簡單理解為:不用聲明的變量(沒有傳實參值就是undefined,即默認值是undefined)
- 實參和形參的多個參數之間用逗號(,)分隔
函數形參和實參數量不匹配時
小結:
- 聲明函數的時候,函數名括號里面的是形參,形參的默認值為 undefined
- 調用函數的時候,函數名括號里面的是實參
- 形參的個數可以和實參個數不匹配,但是結果不可預計,我們盡量要匹配
2.4 函數的返回值
return 語句
返回值:函數調用整體代表的數據;函數執行完成后可以通過return語句將指定數據返回。
// 聲明函數
function 函數名(){
...
return 需要返回的值;
}
// 調用函數
函數名(); // 此時調用函數就可以得到函數體內return后面的值
- 在使用 return 語句時,函數會終止執行,并返回指定的值
- 如果函數沒有 return ,返回的值是 undefined
- return只能返回一個值,多個值用,隔開的話,只會返回最后一個
break ,continue ,return 的區別
- break :結束當前的循環體(如 for、while)
- continue :跳出本次循環,繼續執行下次循環(如 for、while)
- return :不僅可以退出循環,還能夠返回 return 語句中的值,同時還可以結束當前的函數體內的代碼
2.5 arguments的使用
當不確定有多少個參數傳遞的時候,可以用 arguments 來獲取。JavaScript中,arguments實際上它是當前函數的一個內置對象。所有函數都內置了一個 arguments 對象,arguments 對象中存儲了傳遞的所有實參。arguments展示形式是一個偽數組,因此可以進行遍歷。偽數組具有以下特點:
- 只有函數有arguments對象
- 具有 length 屬性
- 按索引方式儲存數據
- 不具有數組的 push , pop 等方法
// arguments 的使用 只有函數才有 arguments對象 而且是每個函數都內置好了這個arguments
function fn() {
// console.log(arguments); // 里面存儲了所有傳遞過來的實參 arguments = [1,2,3]
// console.log(arguments.length);
// console.log(arguments[2]);
// 我們可以按照數組的方式遍歷arguments
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
fn(1, 2, 3);
fn(1, 2, 3, 4, 5);
注意:在函數內部使用該對象,用此對象獲取函數調用時傳的實參。
2.6 函數的兩種聲明方式
-
自定義函數方式(命名函數)
利用函數關鍵字 function 自定義函數方式
// 聲明定義方式 function fn(aru) {...} // 調用 fn();
- 因為有名字,所以也被稱為命名函數
- 調用函數的代碼既可以放到聲明函數的前面,也可以放在聲明函數的后面
-
函數表達式方式(匿名函數)
利用函數表達式方式的寫法如下:
// 這是函數表達式寫法,匿名函數后面跟分號結束 var fn = function(aru){...}; // 調用的方式,函數調用必須寫到函數體下面 fn();
- 因為函數沒有名字,所以也被稱為匿名函數
- 這個fn是變量名,里面存儲的是一個函數
- 函數表達式方式原理跟聲明變量方式是一致的
- 函數調用的代碼必須寫到函數體后面
三、作用域
3.1 作用域概述
通常來說,一段程序代碼中所用到的名字并不總是有效和可用的,而限定這個名字的可用性的代碼范圍就是這個名字的作用域。作用域的使用提高了程序邏輯的局部性,增強了程序的可靠性,減少了名字沖突。
JavaScript(es6前)中的作用域有兩種:
- 全局作用域
- 局部作用域(函數作用域)
3.2 全局作用域
作用于所有代碼執行的環境(整個script標簽內部)或獨立的js文件。
3.3 局部作用域
作用于函數內的代碼環境,就是局部作用域。
因為跟函數有關系,所以也稱為函數作用域。
3.4 jS沒有塊級作用域
塊作用域由 { } 包括。
-
在其他編程語言中(如 java、c#等),在 if 語句、循環語句中創建的變量,僅僅只能在本 if 語句、本循環語句中使用,如下面的Java代碼:
java有塊級作用域:
if(true){ int num = 123; system.out.print(num); // 123 } system.out.print(num); // 報錯
? 以上java代碼會報錯,是因為代碼中 { } 即一塊作用域,其中聲明的變量 num,在 “{ }” 之外不能使用;而與之類似的JavaScript代碼,則不會報錯。
js中沒有塊級作用域(在ES6之前)
if(true){
var num = 123;
console.log(num); //123
}
console.log(num); //123
四、變量的作用域
在JavaScript中,根據作用域的不同,變量可以分為兩種:
- 全局變量
- 局部變量
4.1 全局變量
在全局作用域下聲明的變量叫做全局變量(在函數外部定義的變量)。
- 全局變量在代碼的任何位置都可以使用
- 在全局作用域下 var 聲明的變量 是全局變量
- 特殊情況下,在函數內不使用 var 聲明的變量也是全局變量(不建議使用)
4.2 局部變量
在局部作用域下聲明的變量叫做局部變量(在函數內部定義的變量)
- 局部變量只能在該函數內部使用
- 在函數內部 var 聲明的變量是局部變量
- 函數的形參實際上就是局部變量
4.3 全局變量和局部變量的區別
- 全局變量:在任何一個地方都可以使用,只有在瀏覽器關閉時才會被銷毀,因此比較占內存
- 局部變量:只在函數內部使用,當其所在的代碼塊被執行時,會被初始化;當代碼塊運行結束后,就會被銷毀,因此更節省內存空間
五、作用域鏈
只要是代碼都一個作用域中,寫在函數內部的局部作用域,未寫在任何函數內部即在全局作用域中;如果函數中還有函數,那么在這個作用域中就又可以誕生一個作用域;根據在[內部函數可以訪問外部函數變量]的這種機制,用鏈式查找決定哪些數據能被內部函數訪問,就稱作作用域鏈。
案例分析1:
function f1() {
var num = 123;
function f2() {
console.log( num );
}
f2();
}
var num = 456;
f1();
作用域鏈:采取就近原則的方式來查找變量最終的值
var a = 1;
function fn1() {
var a = 2;
var b = '22';
fn2();
function fn2() {
var a = 3;
fn3();
function fn3() {
var a = 4;
console.log(a); //a的值 ?
console.log(b); //b的值 ?
}
}
}
fn1();
六、預解析
6.1 預解析的相關概念
JavaScript 代碼是由瀏覽器中的 JavaScript 解析器來執行的。
JavaScript 解析器在運行 JavaScript 代碼的時候分為兩步:
預解析和代碼執行。
預解析:在當前作用域下, JS 代碼執行之前,瀏覽器會默認把帶有 var 和 function 聲明的變量在內存中進行提前聲明或者定義,預解析也叫做變量、函數提升。
代碼執行: 從上到下執行JS語句。
注意:預解析會把變量和函數的聲明在代碼執行之前執行完成。
6.2 變量預解析
? 變量的聲明會被提升到當前作用域的最上面,變量的賦值不會提升。
console.log(num); // 結果是多少?
var num = 10; // ?
結果:undefined
注意:變量提升只提升聲明,不提升賦值
6.3 函數預解析
? 函數的聲明會被提升到當前作用域的最上面,但是不會調用函數。
fn();
function fn() {
console.log('打印');
}
結果:控制臺打印字符串 --- ”打印“
注意:函數聲明代表函數整體,所以函數提升后,函數名代表整個函數,但是函數并沒有被調用!
6.4 函數表達式聲明函數問題
函數表達式創建函數,會執行變量提升
fn();
var fn = function() {
console.log('想不到吧');
}
結果:報錯提示 ”fn is not a function"
解釋:該段代碼執行之前,會做變量聲明提升,fn在提升之后的值是undefined;而fn調用是在fn被賦值為函數體之前,此時fn的值是undefined,所以無法正確調用
七、對象
7.1 對象的相關概念
-
什么是對象?
?在 JavaScript 中,對象是一組無序的相關屬性和方法的集合,所有的事物都是對象,例如字符串、數值、數組、函數等。
對象是由屬性和方法組成的。屬性:事物的特征,在對象中用屬性來表示(常用名詞)
方法:事物的行為,在對象中用方法來表示(常用動詞)
為了讓更好地存儲一組數據,對象應運而生:對象中為每項數據設置了屬性名稱,可以訪問數據更語義化,數據結構清晰,表意明顯,方便開發者使用。
JS中的對象表達結構更清晰,更強大。
7.2 創建對象的三種方式
利用字面量創建對象
var star = {
name : 'pink',
age : 18,
sex : '男',
sayHi : function(){
alert('大家好啊~');
}
};
上述代碼中 star即是創建的對象。
-
對象的使用
-
對象的屬性
- 對象中存儲具體數據的 "鍵值對"中的 "鍵"稱為對象的屬性,即對象中存儲具體數據的項
-
對象的方法
- 對象中存儲函數的 "鍵值對"中的 "鍵"稱為對象的方法,即對象中存儲函數的項
-
訪問對象的屬性
對象里面的屬性調用 : 對象.屬性名 ,這個小點 . 就理解為“ 的 ”
-
對象里面屬性的另一種調用方式 : 對象[‘屬性名’],注意方括號里面的屬性必須加引號
示例代碼如下:
console.log(star.name) // 調用名字屬性 console.log(star['name']) // 調用名字屬性
-
調用對象的方法
-
對象里面的方法調用:對象.方法名() ,注意這個方法名字后面一定加括號
示例代碼如下:
star.sayHi(); // 調用 sayHi 方法,注意一定要帶后面的括號
-
-
利用 new Object 創建對象
-
創建空對象
var andy = new Object();
通過內置構造函數Object創建對象,此時andy變量已經保存了創建出來的空對象
-
給空對象添加屬性和方法:通過對象操作屬性和方法的方式,來為對象增加屬性和方法
示例代碼如下:
andy.name = 'pink'; andy.age = 18; andy.sex = '男'; andy.sayHi = function(){ alert('大家好啊~'); }
利用構造函數創建對象
構造函數:是一種特殊的函數,主要用來初始化對象,即為對象成員變量賦初始值,它總與 new 運算符一起使用。我們可以把對象中一些公共的屬性和方法抽取出來,然后封裝到這個函數里面。
-
構造函數的封裝格式:
function 構造函數名(形參1,形參2,形參3) { this.屬性名1 = 參數1; this.屬性名2 = 參數2; this.屬性名3 = 參數3; this.方法名 = 函數體; }
-
構造函數的調用格式
var obj = new 構造函數名(實參1,實參2,實參3)
以上代碼中,obj即接收到構造函數創建出來的對象。
-
注意事項
- 構造函數約定首字母大寫。
- 函數內的屬性和方法前面需要添加 this ,表示當前對象的屬性和方法。
- 構造函數中不需要 return 返回結果。
- 當我們創建對象的時候,必須用 new 來調用構造函數。
-
其他
構造函數,如 Stars(),抽象了對象的公共部分,封裝到了函數里面,它泛指某一大類(class)
創建對象,如 new Stars(),特指某一個,通過 new 關鍵字創建對象的過程我們也稱為對象實例化 -
new關鍵字的作用
- 在構造函數代碼開始執行之前,在內存中創建一個空對象;
- 修改this的指向,把this指向創建出來的空對象;
- 執行函數的代碼
- 在函數完成之后,返回this---即創建出來的對象
7.3 遍歷對象
?for...in 語句用于對數組或者對象的屬性進行循環操作。
其語法如下:
for (變量 in 對象名字) {
// 在此執行代碼
}
語法中的變量是自定義的,它需要符合命名規范,通常我們會將這個變量寫為 k 或者 key。
for (var k in obj) {
console.log(k); // 這里的 k 是屬性名
console.log(obj[k]); // 這里的 obj[k] 是屬性值
}
八、內置對象
8.1 內置對象
? JavaScript 中的對象分為3種:自定義對象 、內置對象、 瀏覽器對象
? 前面兩種對象是JS 基礎 內容,屬于 ECMAScript; 第三個瀏覽器對象屬于 JS 獨有的, JS API 講解內置對象就是指 JS 語言自帶的一些對象,這些對象供開發者使用,并提供了一些常用的或是最基本而必要的功能(屬性和方法),內置對象最大的優點就是幫助我們快速開發
? JavaScript 提供了多個內置對象:Math、 Date 、Array、String等
8.2 查文檔
? 查找文檔:學習一個內置對象的使用,只要學會其常用成員的使用即可,我們可以通過查文檔學習,可以通過MDN/W3C來查詢。
? Mozilla 開發者網絡(MDN)提供了有關開放網絡技術(Open Web)的信息,包括 HTML、CSS 和萬維網及 HTML5 應用的 API。
? MDN:https://developer.mozilla.org/zh-CN/
8.3 Math對象
? Math對象不是構造函數,它具有數學常數和函數的屬性和方法。跟數學相關的運算(求絕對值,取整、最大值等)可以使用 Math 中的成員。
屬性、方法名 | 功能 |
---|---|
Math.PI | 圓周率 |
Math.floor() | 向下取整 |
Math.ceil() | 向上取整 |
Math.round() | 四舍五入版 就近取整 注意 -3.5 結果是 -3 |
Math.abs() | 絕對值 |
Math.max()/Math.min() | 求最大和最小值 |
Math.random() | 獲取范圍在[0,1)內的隨機值(隨機小數) |
? 注意:Math.round(遇到.5,往大取,因此負值-x.5結果是-x)
? 獲取指定范圍內的隨機整數:
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值
}
// 要求用戶猜 1~50之間的一個數字 但是只有 10次猜的機會
var random = getRandom(1, 50),
i = 0;
while (i <= 10) { // 死循環
var num = prompt('你來猜? 輸入1~50之間的一個數字');
i++;
if (num > random) {
alert('你猜大了');
} else if (num < random) {
alert('你猜小了');
} else {
alert('你好帥哦,猜對了');
break; // 退出整個循環結束程序
}
}
8.4 日期對象
Date 對象和 Math 對象不一樣,Date是一個構造函數,所以使用時需要實例化后才能使用其中具體方法和屬性。Date 實例用來處理日期和時間
-
使用Date實例化日期對象
- 獲取當前時間必須實例化:
var now = new Date();
- 獲取指定時間的日期對象
var future = new Date('2019-5-1 8:8:8'); var future1 = new Date('2019/5/1');
注意:如果創建實例時并未傳入參數,則得到的日期對象是當前時間對應的日期對象
使用Date實例的方法和屬性
-
通過Date實例獲取總毫米數
-
總毫秒數的含義
? 基于1970年1月1日(世界標準時間)起的毫秒數
-
獲取總毫秒數
// 實例化Date對象 var now = new Date(); // 1. 用于獲取對象的原始值 console.log(date.valueOf()) console.log(date.getTime()) // 2. 簡單寫可以這么做 var now = + new Date(); // 3. HTML5中提供的方法,有兼容性問題 var now = Date.now();
-
8.5 數組對象
創建數組的兩種方式
-
字面量方式
-
示例代碼如下:
var arr = [1,"test",true];
-
-
new Array()
-
示例代碼如下:
var arr = new Array(); var arr1 =new Array(2) //等價于 arr1=[empty*2] 表示有個2個空數據組,length為2 var arr2 =new Array(2,5) //等價于 arr2=[2,5]
? 注意:上面代碼中arr創建出的是一個空數組,如果需要使用構造函數Array創建非空數組,可以在創建數組時傳入參數
? 參數傳遞規則如下:
如果只傳入一個參數,則參數規定了數組的長度
如果傳入了多個參數,則參數稱為數組的元素
-
檢測是否為數組
-
instanceof 運算符
-
instanceof 可以判斷一個對象是否是某個構造函數的實例
var arr = [1, 23]; var obj = {}; console.log(arr instanceof Array); // true console.log(obj instanceof Array); // false
-
-
Array.isArray()
-
Array.isArray()用于判斷一個對象是否為數組,isArray() 是 HTML5 中提供的方法
var arr = [1, 23]; var obj = {}; console.log(Array.isArray(arr)); // true console.log(Array.isArray(obj)); // false
-
添加刪除數組元素的方法
- 數組中有進行增加、刪除元素的方法,部分方法如下表
注意:push、unshift為增加元素方法;pop、shift為刪除元素的方法
var arr = [1,2,3];
arr.push(4,'pink');
console.log(arr.push(5)); //6 返回數組的長度
arr.unshift(6,'red')
console.log(arr.pop()); //pink 返回的是元素的最后一個元素
arr.shift();
console.log(arr)
數組排序
- 數組中有對數組本身排序的方法,部分方法如下表
注意:sort方法需要傳入參數來設置升序、降序排序
- 如果傳入“function(a,b){ return a-b;}”,則為升序
- 如果傳入“function(a,b){ return b-a;}”,則為降序
var arr = [1,3,2,5];
var arr1 =[1,88,56,32,8]
arr.reverse();//翻轉數組
arr1.sort(function(a,b){ return a-b;})//升序冒泡排序
數組索引方法
- 數組中有獲取數組指定元素索引值的方法,部分方法如下表
//查找兩組數組不同值案例【數組去重】
var Arr = ["寇曉麗", "馬曉晗", "王思聰", "張綠", "李德", "鄭萍", "張凱", "張嘉成", "葛云俠", "楊磊", "劉東", "王可可", "陳澤文", "李嘉琪", "段佳琦", "黃燕", "邱淑鴻", "宋翔宇", "王波", "樊琳", "王兆國", "許成", "李興"];
var currentArr = ["寇曉麗", "馬曉晗", "張綠", "李德", "鄭萍", "張凱", "張嘉成", "葛云俠", "楊磊", "劉東", "陳澤文", "李嘉琪", "段佳琦", "黃燕", "邱淑鴻", "宋翔宇", "王波", "樊琳", "王兆國", "許成", "李興"];
var unfinish = new Array();
for (var i = 0; i < Arr.length; i++) {
if (currentArr.indexOf(Arr[i]) === -1) {
unfinish.push(Arr[i])
}
}
console.log(unfinish)
數組轉換為字符串
- 數組中有把數組轉化為字符串的方法,部分方法如下表
注意:join方法如果不傳入參數,則按照 “ , ”拼接元素
var arr = [1,2,3]
console.log(arr.toString()) // 1,2,3
console.log(arr.join('')) // 1,2,3
console.log(arr.join('|')) // 1|2|3
其他方法
- 數組中還有其他操作方法,同學們可以在課下自行查閱學習
8.6 字符串對象
基本包裝類型
為了方便操作基本數據類型,JavaScript 還提供了三個特殊的引用類型:String、Number和 Boolean。
基本包裝類型就是把簡單數據類型包裝成為復雜數據類型,這樣基本數據類型就有了屬性和方法。
// 下面代碼有什么問題?
var str = 'andy';
console.log(str.length);
按道理基本數據類型是沒有屬性和方法的,而對象才有屬性和方法,但上面代碼卻可以執行,這是因為 js 會把基本數據類型包裝為復雜數據類型,其執行過程如下 :
// 1. 生成臨時變量,把簡單類型包裝為復雜數據類型
var temp = new String('andy');
// 2. 賦值給我們聲明的字符變量
str = temp;
// 3. 銷毀臨時變量
temp = null;
字符串的不可變
指的是里面的值不可變,雖然看上去可以改變內容,但其實是地址變了,內存中新開辟了一個內存空間。
當重新給字符串變量賦值的時候,變量之前保存的字符串不會被修改,依然在內存中。重新給字符串變量賦值,會重新在內存中開辟空間,這個特點就是字符串的不可變。
?由于字符串的不可變,在大量拼接字符串的時候會有效率問題,因為非常占內存空間
根據字符返回位置
字符串通過基本包裝類型可以調用部分方法來操作字符串,以下是返回指定字符的位置的方法:
案例:查找字符串"abcoefoxyozzopp"中所有o出現的位置以及次數
- 先查找第一個o出現的位置
- 然后 只要indexOf 返回的結果不是 -1 就繼續往后查找
- 因為indexOf 只能查找到第一個,所以后面的查找,利用第二個參數,當前索引加1,從而繼續查找
var str = 'abcoefoxyozzopp';
var index = str.indexOf('o');
var pos = [index];
while (index !== -1) {
console.log(index)
index = str.indexOf('o', index + 1);
pos.push(index)
}
pos.pop()
console.log(pos)
var time = pos.length
console.log(time)
根據位置返回字符
字符串通過基本包裝類型可以調用部分方法來操作字符串,以下是根據位置返回指定位置上的字符:
在上述方法中,charCodeAt方法返回的是指定位置上字符對應的ASCII碼,ASCII碼對照表如下:
案例:判斷一個字符串 'abcoefoxyozzopp' 中出現次數最多的字符,并統計其次數
- 核心算法:利用 charAt() 遍歷這個字符串
- 把每個字符都存儲給對象, 如果對象沒有該屬性,就為1,如果存在了就 +1
- 遍歷對象,得到最大值和該字符
注意:在遍歷的過程中,把字符串中的每個字符作為對象的屬性存儲在對象總,對應的屬性值是該字符出現的次數
var str = 'abcoefoxyozzopp';
var obj = new Object();
for(var i=0; i < str.length; i++) {
var charts = str.charAt(i);
if(obj[charts]){
obj[charts]++;
}else{
obj[charts] = 1;
}
}
var max=0,chartKey='';
for(key in obj){
if(obj[key] > max){
max = obj[key]
chartkey = key
}
}
console.log(chartkey,max)
字符串操作方法
字符串通過基本包裝類型可以調用部分方法來操作字符串,以下是部分操作方法:
replace()方法
replace() 方法用于在字符串中用一些字符替換另一些字符,其使用格式如下:
字符串.replace(被替換的字符串, 要替換為的字符串);
split()方法
split()方法用于切分字符串,它可以將字符串切分為數組。在切分完畢之后,返回的是一個新數組。
其使用格式如下:
字符串.split("分割字符")
九、簡單數據類型和復雜數據類型
9.1 簡單數據類型
簡單類型(基本數據類型、值類型):在存儲時變量中存儲的是值本身,包括string ,number,boolean,undefined,null
9.2 復雜數據類型
復雜數據類型(引用類型):在存儲時變量中存儲的僅僅是地址(引用),通過 new 關鍵字創建的對象(系統對象、自定義對象),如 Object、Array、Date等;
9.3 堆棧
- 堆??臻g分配區別:
1、棧(操作系統):由操作系統自動分配釋放存放函數的參數值、局部變量的值等。其操作方式類 似于數據結構中的棧;
簡單數據類型存放到棧里面
2、堆(操作系統):存儲復雜類型(對象),一般由程序員分配釋放,若程序員不釋放,由垃圾回收機制回收。
-
簡單數據類型的存儲方式
? 值類型變量的數據直接存放在變量(??臻g)中,直接開辟一個空間存放值
-
復雜數據類型的存儲方式
? 引用類型變量(??臻g)里存放的是地址(十六進制表示,指向堆里的數據),真正的對象實例存放在堆空間中
9.4 簡單類型傳參
?函數的形參也可以看做是一個變量,當我們把一個值類型變量作為參數傳給函數的形參時,其實是把變量在??臻g里的值復制了一份給形參,那么在方法內部對形參做任何修改,都不會影響到的外部變量。
function fn(a) {
a++;//形參在內存也開辟了一個新地址a,存上(復制了)x存的數據
console.log(a); // 11
}
var x = 10;
fn(x);
console.log(x);//10
9.5 復雜數據類型傳參
函數的形參也可以看做是一個變量,當我們把引用類型變量傳給形參時,其實是把變量在??臻g里保存的堆地址復制給了形參,形參和實參其實保存的是同一個堆地址,所以操作的是同一個對象。
function Person(name) {
this.name = name;
}
function f1(x) { // x = p //在棧中開辟一個地址x,存的是(復制得到)p中的地址
console.log(x.name); // 2. 這個輸出什么 ? 劉德華
x.name = "張學友";
console.log(x.name); // 3. 這個輸出什么 ? 張學友
}
var p = new Person("劉德華");
console.log(p.name); // 1. 這個輸出什么 ? 劉德華
f1(p);
console.log(p.name); // 4. 這個輸出什么 ? 張學友