JS高級教程
1.探討了JS面向對象程序設計和繼承的方式狰腌,以及如何在HTML等標記語言中使用它摆尝。在深入剖析了
事件和事件處理后,又解釋瀏覽器檢測技術.
第一章: JS簡介
從當初簡單的為了表單驗證的語言七问,變成了現(xiàn)在能夠處理復雜計算和交互章母,擁有閉包、匿名函數(shù)因宇,
甚至元編程等特性七婴。
要想全面理解和掌握JS,關鍵在于弄清楚它的本質察滑、歷史和局限性
1.JS簡史
客戶端語言--- 為了解決撥號打厘,表單驗證緩慢的問題
ECMAScript的新腳本語言的標準。
1.2 JS實現(xiàn)
JS由三部分組成:核心(ECMAScript)杭棵、文檔對象模型(DOM)婚惫、瀏覽器對象模型(BOM)
1.2.1 ECMAScript
ECMAScript與Web瀏覽器無關氛赐。ECMAScript這門語言并不包含輸入和輸出定義,它只是基礎先舷。
而Web瀏覽器是ECMAScript實現(xiàn)可能的宿主環(huán)境艰管。宿主環(huán)境不僅提供基本的ECMAScript實現(xiàn),
而且也會提供該語言的擴展--如DOM蒋川,提供了更多具體的功能牲芋,以便實現(xiàn)各種操作。
ECMAScript只規(guī)定了下面:
1.語法
2.類型
3.語句
4.關鍵字
5.保留子
6操作符
7對象
1.2.2 文檔對象模型(DOM)
文檔對象模型是針對XML但經(jīng)過擴展用于HTML的應用程序編程接口(API)捺球。DOM把整個頁面映射為
一個多層節(jié)點結構缸浦。HTML或XML頁面的中的每個組成部分都是某種類型的節(jié)點。
用戶可以根據(jù)需求隨意控制任何節(jié)點氮兵。
1.為什么要使用DOM
由于瀏覽器不兼容的問題裂逐,擔心成為一種趨勢,制定一種標準能夠都兼容泣栈,減少代碼量卜高。
2.DOM級別
DOM1:DOM核心和DOM HTML。
DOM核心規(guī)定的是如何映射基于XML的文檔結構南片,簡化對文檔結構的操作掺涛。
DOM HTMl在核心加一擴展,添加了對HTML的對象和方法疼进。
DOM2:在原來DOM基礎上擴充了鼠標和用戶界面事件薪缆、范圍、遍歷伞广。
DOM3:進一步擴展了DOM,引入了以統(tǒng)一方式加在和保存文檔的方法拣帽。
1.2.3 瀏覽器對象模型(BOM)
只處理瀏覽器窗口和框架。也習慣把所有針對瀏覽器的JS擴展放上去赔癌,
擴展: 1.彈出新瀏覽器窗口
2.移動诞外、縮放和關閉
3.提供瀏覽器詳細信息
4.提供所加載頁面的詳細信息
5.提供分辨率信息
6.對cookie的支持
7.XMLHttpRequest 這樣的自定義對象澜沟。
小結:
JS是一種專為網(wǎng)頁交互而設計的腳本語言灾票,由三個不同的部分組成:
1.ECMAScript, 提供核心語言功能茫虽。
2.文檔對象模型:提供訪問和操作網(wǎng)頁內容的方法和接口
3.瀏覽器對象模型:提供與瀏覽器交互的方法和接口
第二章 在HTML中使用JS
如何讓JS既能與HTML頁面共存刊苍,又不影響那些頁面在其他瀏覽器中的呈現(xiàn)效果。
最佳的辦法是:添加同意的腳本支持濒析。
2.1<script>元素
六個屬性: async:異步加載正什,只對外部腳本有效。
表示應該立即下載号杏,但不應妨礙頁面其他操作婴氮,如下載資源或等待加載其他腳本
charset: 表示通過src屬性指定的代碼的字符集斯棒。
defer: 表示腳本可以延遲到文檔完全被解析和顯示之后再執(zhí)行。
src: 資源文件主经。外部腳本文件荣暮。
type: 內容類型。常用的 text/javascript
language :廢棄
兩種使用方式: 直接嵌入罩驻、外部引入穗酥。
直接嵌入:
如果是一個函數(shù)定義,解釋器會解釋到一個函數(shù)的定義惠遏,然后將該定義保存到自己的環(huán)境中砾跃。
在解釋器對<script>元素的內部所有代碼求值完畢以前,其余內容不會被加載节吮。
外部:
1.如果外部抽高,同時在標簽中加入嵌入代碼,嵌入代碼會被忽略透绩。
2.只要不存在defer和async屬性厨内,它會按照順序解析。
2.1.1 標簽位置:
慣例渺贤,放在head中雏胃。
壞處:1.必須等head中的JS全部下載,才會開始呈現(xiàn)內容志鞍。
為了避免瞭亮,會將JS放在body元素中的內容后面。
2.1.2 延遲腳本:defer :放在底部比較好固棚。
含義:腳本會被延遲到整個頁面都解析完畢后運行统翩。(也就是遇到</html>再執(zhí)行。)
一般但不保證一定此洲,會先于DOMContentLoaded事件執(zhí)行厂汗。
defer只支持外部腳本,因此嵌入腳本有 defer,會忽略呜师。
2.1.3 異步腳本:async
異步加載一定會在頁面的load事件前執(zhí)行娶桦。 但可能會在DOMContentLoaded事件觸發(fā)之前或之后進行。
2.1.4 在XHTML中的用法
可擴展超文本標記語言(XHMTL)汁汗,是將HTML作為XML的應用重新定義的一個標準衷畦。
XHTML的語法規(guī)則是非常嚴格的。
2.2 嵌入代碼與外部文件
比較強調使用外部文件
可維護性
可緩存
適應未來
2.3 文檔模式
現(xiàn)在使用的是文檔類型(doctype)實現(xiàn)的知牌。
一般使用標準模式祈争。
<!DOCTYPE html>
文檔模式分為兩種:混雜模式和標準模式。 如果不寫上面的話角寸,默認開啟標準模式菩混。
2.4 <noscript>元素
如何解決瀏覽器不支持JS時忿墅,如何讓頁面平穩(wěn)退化:
<noscript>. 用來代替在不支持的JS的瀏覽器的情況下,顯示代替內容沮峡。
情況 :1球匕。不支持腳本
2.支持腳本,但腳本被禁用帖烘。
2.5 小結
第三章 基本概念
3.1 語法
3.1.1 區(qū)分大小寫
變量亮曹、函數(shù)名、操作符都區(qū)分大小寫秘症。
3.1.2 標識符
其實就是變量名照卦,命名規(guī)則
3.1.4 嚴格模式
嚴格模式是為JS定義了一種不同的解析與執(zhí)行模型。對待一些不確定的行為乡摹,將會進行處理役耕,對不安全的
操作會拋出錯誤。
方法: 代碼頂部: "use strict"; 或者指定一個函數(shù)
function doSomething(){
“use strict”聪廉;
}
這是一個編譯指示瞬痘,切換到嚴格模式。 嚴格模式下板熊,JS執(zhí)行結果會有很大不同
3.1.5 語句
以;結尾框全。
3.2 關鍵字和保留子。
3.3 變量
變量時松散類型干签,即弱關系類型津辩。指的是可以保存任何類型的數(shù)據(jù)。換句話說容劳,每個變量僅僅是一個用于保存
值的占位符而已喘沿。
var message: 未經(jīng)初始化的變量,會保存一個特殊的值undefined竭贩。
注意變量的作用域蚜印。
3.4 數(shù)據(jù)類型
五種簡單數(shù)據(jù)類型:Undefined|Null|Boolean|Number和String.
一種復雜數(shù)據(jù)類型:Object. 本質上是由一組無序的名值對組成的。 不支持創(chuàng)建自定義類型的極致留量。
3.4.1 typeof 操作符
檢測給定變量的數(shù)據(jù)類型窄赋。
使用方法: 他是一個操作符而不是函數(shù),因此例子中的圓括號盡管可以使用肪获,但不是必需的寝凌。
var message="some string";
alert(typeof message); //返回“string”
alert(typeof (message)); //返回...
alert(typeof 95); //返回number
alert(typeof null); //返回object. 因為把他看作是一個空的對象引用柒傻。
3.4.2 Undefined類型
var message;
alert(message); //"undefined"
alert(age); //產生錯誤
上面的例子孝赫,包含undefined值的變量和尚未定義的變量還是不一樣的。
對于尚未聲明過的變量红符,只能執(zhí)行一項操作青柄,即使用typeof操作符檢測其數(shù)據(jù)類型伐债。
未初始化、未聲明的變量使用typeof操作符同樣也會返回undefined值致开。
var message;
alert(typeof message); //'undefined'
alert(typeof age); //'undefined'
明智的做法:顯式地初始化變量峰锁。當使用typeof時,這樣就能檢測出變量是沒有被聲明双戳,而不是尚未初始化虹蒋。
3.4.3 Null 類型
Null類型是第二個只有一個值的數(shù)據(jù)類型,這個特殊的值是null飒货。從邏輯上看魄衅,null值表示一個空對象指針。
var car=null;
alert(typeof car);
如果定義的變量準備用來保存對象塘辅,那么最好初始化為null. 這樣檢測值就能知道是否已經(jīng)保存了一個對象的引用
if(car!=null)
實際上晃虫,undefined值是派生自null值的,因此:
alert(null ==undefined; //true
如果是對象扣墩,記得聲明成null哲银。可以區(qū)分null和undefined.
3.4.4 Boolean類型
true和false呻惕,這兩個值與數(shù)字值不是一回事荆责。true不一定等于1,false不一定等于0。
所有類型的值都有與這兩個Boolean值等價的值亚脆〔菅玻可使用Boolean();
Boolean() 會自動轉換在if語句中。
true false
String 任何非空 空字符
Number 任何非零數(shù)字值 0或NaN
Object 任何對象 null
Undefined n/s undefined
eg: var message="hello";
if(message) //這里使用了轉化 Boolean()
3.4.5 Number類型
表示整數(shù)和浮點數(shù)型酥。
八進制: 07;
十六進制 0xAF;
注意永遠不要測試某個特定的浮點數(shù)值山憨。
if(a+b==0.3) //不要這樣做,因為會有誤差弥喉。 可能 0.1+0.2的結果是=0郁竟。30000000000004
2.數(shù)值范圍
Number.MIN_VALUE : 5e-324
Number.MAX_VALUE:1.7976931348623157e+308
如果超出范圍會轉化成特殊的Infinity值。
確定有窮:isFinite()函數(shù)由境。
3.NaN(not a number)
非數(shù)值是一個特殊的數(shù)值棚亩,這個數(shù)值用于表示一個本來要返回數(shù)值的操作數(shù)未返回數(shù)值的情況。(這樣不會拋錯虏杰。)
特點:
1.任何涉及NaN的操作都會返回NaN讥蟆。
2.NaN與任何值都不相等,包括NaN本身纺阔。
alert(NaN ==NaN) //false
針對這個定義了瘸彤,isNaN();(是否為數(shù)值).他會嘗試這個值能否轉化為數(shù)值。
alert(isNaN(NaN)); //true
alert(isNaN(10)); //false (10是一個數(shù)值)
alert(isNaN("blue")) //true (不能轉化)
4.數(shù)值轉換
三個函數(shù)笛钝,把非數(shù)值轉化為 數(shù)值: Number()\parseInt()和parseFloat()质况。
Number():有點復雜愕宋。
parseInt():更常用: 從第一個非空格字符開始,如果不是數(shù)字结榄,返回NaN.可指定進制中贝。
parseFloat():和parseInt()類似,
3.4.6 String 類型
單雙引號都可以是字符串臼朗。
1.字符字面量
String數(shù)據(jù)類型包含一些特殊的字符字面量邻寿,也叫轉義序列,用于表示非打印字符视哑。
2.字符串的特點:
ECMAScript中的字符串是不可變的老厌。一旦創(chuàng)建,他們的值不可改變黎炉。如果改變值枝秤,先銷毀,后用另一個包含
新值的字符串填充該變量慷嗜。
3.轉換為字符串
toString()方法:若使用參數(shù)侥猩,代表進制删性。 不適用于null\undefined
eg: var age=11;
var ageString=age.toString(); // “11” 無參數(shù)缺菌。
var ageString=age.toString(2)盒让; //“01011” 二進制
String():可使用不知道要轉換的值是不是null或undefined的情況下。
var value1=null;
var value2=undefined;
alert(String(value1)); //"null"
alert(String(value2)); //"undefined"
3.4.7 Object類型
var o=new Object();
其中缭乘,在ECMAScript中沐序,Object類型是所有它的實例的基礎。
Object的每個實例都有的屬性和方法:
1.Constructor
2.hasOwnProperty("name")
3.isPrototypeOf(object)堕绩。
4.propertyIsEnumerble("name"):檢查給定屬性能否使用for-in來枚舉策幼。
5.toLocaleString()
6.toString()
7.valueOf()
3.5 操作符
ECMAScript操作符的與眾不同之處在于,他們能夠適用于很多值奴紧,字符串特姐、數(shù)字值、布爾值黍氮,甚至對象唐含。
在使用對象時,通常會先調用對象的valueOf()和toString()
注意:一元加和減操作符
在對非數(shù)值應用一元加操作符時沫浆,該操作符會想Number()轉型函數(shù)一樣對這個值執(zhí)行準換捷枯。
var s1="01";
var s3="z";
s1=+s1; //變?yōu)閿?shù)值1
s3=+s3; //變?yōu)镹aN.
3.5.4 乘性操作符
與JAVA不同的是,操作數(shù)為非數(shù)值的情況下會執(zhí)行自動的類型轉換专执。
3.5.7 相等操作符
==淮捆、!=,注意:
要比較相等性之前,不能將null和undefined轉換成其他任何值争剿。
null == 0 false
undefined ==0 false
==\ === 不一樣已艰,兩個==轉換類型再比較痊末,而===直接進行比較蚕苇。
“55” == 55; //true,因為轉換后想等
"55" ===55; //false,因為不同的數(shù)據(jù)類型不相等
3.5.8 條件操作符
b= a?c:d;
3.5.9 賦值操作符
注意: x=y+7 等價于x=x(y+7)
3.5.10逗號操作符
用于賦值時凿叠,逗號操作符總會返回表達式中的最后一項涩笤。
var num=(5,8,9,0); //num=0
3.6 語句
3.6.4 for語句
if語句: 注意: ECMAScript中不存在塊級作用域。因此在循環(huán)內部定義的變量也可以在外部訪問到盒件。
var count=10;
for(var i=0;i<count;i++){
}
alert(i);
3.6.5 for-in語句:建議使用前蹬碧,先確認該對象是不是null或undefined.
for-in語句是一種精準的迭代語句,可以用來枚舉對象的屬性炒刁。
for(var propName in window){
document.write(propName);
}
ECMAScript對象的屬性沒有順序恩沽。因此,for-in輸出的順序是不可預測的翔始。
3.7 break和continue語句
獨特的使用辦法:label語句罗心,可以返回到代碼中特定的位置。
var num=0;
outermost:
for(var i=0;i<10;i++){
for(var j=0;j<10;j++){
if(i==5 && j==5){
break outermost;
}
num++;
}
}
alert(num); //55
添加了標簽以后城瞎,會導致break語句不僅會退出內部的for語句渤闷,也會退出外部的for語句。為此脖镀,當變量i和
j都等于5時飒箭。num等于55.
var num=0;
outermost:
for(var i=0;i<10;i++){
for(var j=0;j<10;j++){
if(i==5 && j==5)
continue outermost;
}
num++;
}
alert(num); //95
在這種情況下,continue會強制繼續(xù)執(zhí)行循環(huán)————退出內部循環(huán)蜒灰,執(zhí)行外部循環(huán)弦蹂。
謹慎使用label語句,如果使用强窖,一定要使用描述性的標簽盈匾,同時不要嵌套過多的循環(huán)。
3.6.8 with語句 : 大量使用會導致性能下降毕骡,調試困難削饵。大程序不建議使用
with語句的作用是將代碼的作用域設置到一個特定的對象中:
with(expression) statement;
舉例,假如多次使用一個對象未巫,可以這樣用窿撬,用法:
原來:
var qs=location.search.substring(1);
var hostName=location.hostname;
更改后:
with(location){
var qs=search.substring(1);
var hostName=hostname;
}
3.6.9 switch 語句
JS中的switch語句比其他語言強大很多。switch的表達式可以傳遞任何數(shù)據(jù)類型叙凡。
switch("hello world"){
case "hello"+" world":
alert("1");
break;
case "goodbye":
alert("12");
break;
}
也可以當做if語句來使用劈伴。
var num=25;
swtich(true){
case num<0:
alert("1");
break;
case nume>=0 &&num<=10:
alert("12");
break;
}
3.7 函數(shù)
在使用return;時,將會返回一個undefined值。這種用法一般用在需要提前停止函數(shù)執(zhí)行而又不需要返回值的情況下跛璧。
3.7.1 理解參數(shù)
ECMAScript函數(shù)的參數(shù)與大多數(shù)語言中函數(shù)的參數(shù)不同严里。它可以傳遞很多個參數(shù),即使定義只定義了幾個追城。原因是ECMAScript中的參數(shù)在內部是用一個數(shù)組(arguments)來表示刹碾。其實arguments對象只是與數(shù)組類似,因為可以使用方括號語法訪問他的每一個元素座柱。
函數(shù)一個重要的特點:
1.命名的參數(shù)只提供便利迷帜,但不是必須的。
2.此外色洞,arguments對象可以與命名參數(shù)一起使用戏锹。
3.arguments的值永遠與對應命名參數(shù)的值保持同步:當修改arguments的值,命名參數(shù)值也會改變火诸。但是命名參數(shù)改變锦针,
arguments的值不會改變。
4.當你只傳入一個參數(shù)時置蜀,那么修改arguments[1],并不會影響第二個命名參數(shù)奈搜。因為arguments對象長度由傳入?yún)?shù)決定
而不是由定義函數(shù)時的命名參數(shù)的個數(shù)決定的。
5.沒有傳遞值的命名參數(shù)自動被賦予undefined盾碗。
ECMAScript中的所有參數(shù)傳遞的都是值媚污,不可能通過引用傳遞參數(shù)。
3.7.2 沒有重載
如果有兩個同名函數(shù)廷雅,則該名字只屬于后定義的函數(shù)耗美。
第四章 變量、作用域和內存問題
4.1 基本類型和引用類型的值
基本類型值指的是簡單的數(shù)據(jù)段航缀。
引用類型值指的是那些可能由多個值構成的對象商架。
4.1.1 動態(tài)的屬性
只能為引用類型的值動態(tài)添加屬性,普通的數(shù)據(jù)類型不能添加屬性芥玉。
var name="NAC";
name.age=27; //錯誤的
4.1.2 復制變量值
基本數(shù)據(jù)類型是復制一個副本蛇摸,對象是引用,復制的是一個指針灿巧,指向同一個對象赶袄。
4.1.3 傳遞參數(shù)
值傳遞:復制一個副本。
指針傳遞:是特殊的值傳遞抠藕,它可以改變指向對象的值饿肺,也可以改變指向的對象。
引用傳遞:可以改變指向對象的值盾似,但是不能改變指向的對象敬辣,他是對象的別名。
4.1.4 檢測類型
使用typeof
instanceof
4.2 執(zhí)行環(huán)境及作用域
執(zhí)行環(huán)境定義了變量或函數(shù)有權訪問的其他數(shù)據(jù),決定它們各自的行為溉跃。 每個執(zhí)行環(huán)境都有一個與之關聯(lián)的變量對象村刨,環(huán)境
中定義的所有變量和函數(shù)都保存在這個對象中。雖然我們編寫的代碼無法訪問這個對象撰茎,但解析器在處理數(shù)據(jù)時會在后臺
使用它嵌牺。
全局執(zhí)行環(huán)境是最外圍的一個執(zhí)行環(huán)境。不同的宿主環(huán)境乾吻,表示執(zhí)行環(huán)境的對象也不一樣髓梅。在web中拟蜻,全局執(zhí)行環(huán)境被認為
window對象绎签,所有的全局變量和函數(shù)都作為window對象的屬性和方法創(chuàng)建的。
當代碼在一個環(huán)境中執(zhí)行時酝锅,會創(chuàng)建變量對象的一個作用鏈诡必。作用鏈的用途,是保證對執(zhí)行環(huán)境有權訪問的所有變量和函數(shù)的
有序訪問搔扁。作用域鏈的前端爸舒,始終都是當前執(zhí)行的代碼所在環(huán)境的變量對象。如果這個環(huán)境是函數(shù)稿蹲,則將其活動對象作為變量對象扭勉,即arguments對象。一級一級的包含苛聘。
標識符解析是沿著作用域鏈一級一級地搜索標識符的過程涂炎。搜索過程使用從前段開始,然后逐漸向后回溯设哗。
此外唱捣,在局部作用域中定義的變量可以在局部環(huán)境中與全局變量互換使用。
內部環(huán)境可以通過作用域鏈訪問所有的外部環(huán)境网梢,但外部環(huán)境不能訪問內部環(huán)境中任何變量和函數(shù)震缭。
4.2.1 延長作用域鏈
有一些辦法可以延長作用鏈,會在作用鏈的前端臨時增加一個變量對象战虏,使用完后移除拣宰。
兩種情況:
1.try-catch的catch塊:會創(chuàng)建一個新的變量對象,其中包含錯誤對象的聲明烦感。
2.with語句: 會將制定的對象添加到作用域鏈中巡社。
function buildUrl(){
var qs="?debug=true";
with(location){
var url=href+qs;
}
return url;
}
在這個函數(shù)中,首先with函數(shù)接受了location對象啸盏,把它放在了作用鏈的前端重贺,并且引用它的屬性href(location.
href)。使用了with后,內部url气笙,可以被外部執(zhí)行環(huán)境接受次企。
4.2.2 沒有塊級作用域
if(true){
var color="blue";
}
alert(color); //"blue"
在c語言中,color在if中執(zhí)行完后,會銷毀潜圃。后面會報錯缸棵。而在JS中,if聲明的變量會添加到當前的執(zhí)行環(huán)境谭期。
再舉例堵第,
for(var i=0;i<10;i++){
}
alert(i); //10
對于有塊級作用域的語言,for所定義的變量只存在循環(huán)中隧出。而在JS中踏志,執(zhí)行完for,依然存在。
1.聲明變量
使用var 聲明的變量會自動被添加到最接近的環(huán)境中胀瞪。
2.查詢標識符
從作用鏈前端開始查詢针余,查詢到停止。
4.3 垃圾收集
JS具有自動垃圾收集機制凄诞,也就是說圆雁,執(zhí)行環(huán)境會負責管理代碼執(zhí)行過程中使用的內存。
垃圾收集器會按照固定的時間間隔帆谍,周期性地執(zhí)行這一操作:找出不再繼續(xù)使用的變量伪朽,然后釋放其占用的內存。
工作機制:垃圾收集器必須追蹤哪個變量游泳哪個變量沒用汛蝙,對于不再有用的變量搭上標記烈涮,以備將來回收,有兩種
策略患雇。
4.3.1 標記清除
垃圾收集器在運行的時候會給儲存在內存中的所有變量都加上標記跃脊。然后,他會去掉環(huán)境中的變量以及被環(huán)境中的變量引用的變量的標記苛吱。而在此之后再被加上標記的變量將視為準備刪除的變量酪术。
4.3.2 引用計數(shù)
另一種不太常見的垃圾手機策略叫做引用計數(shù)。含義是跟蹤記錄每個值被引用的次數(shù)翠储。
當一個值被變量引用時绘雁,則該值的引用次數(shù)加1。當變量的值被其他值所取代援所,引用數(shù)減1.
當變?yōu)?時庐舟,說明無法再訪問這個值,當垃圾收集器下次運行時住拭,他會釋放引用為0的內存挪略。
循環(huán)引用:會導致無法銷毀內存历帚,所以不再采用。
BOM和DOM中的對象就是使用C++以COM對象的形式實現(xiàn)的杠娱,c++采用引用計數(shù)挽牢,當IE中涉及COM對象,就會存在循環(huán)引用的問題摊求。
后來改版后禽拔,DOM和BOM都轉換成了JS對象,避免了常見的內存泄漏室叉。
4.3.3 性能問題
4.3.4 管理內存
分配給Web瀏覽器的可用內存數(shù)量通常比程序的少睹栖。目的是處于安全方面的考慮,目的防止運行的網(wǎng)頁耗盡呢堃導致系統(tǒng)崩潰茧痕。內存限制不僅影響給變量分配內存野来,同時還影響一個線程中同時執(zhí)行的語句數(shù)量。
因此凿渊,優(yōu)化內存最佳的方式梁只,就是為執(zhí)行中的代碼只保存必要數(shù)據(jù)缚柳,一旦數(shù)據(jù)不用埃脏,設為null,來釋放引用---解除引用秋忙。 這適用于大多數(shù)全局變量和全局對象的屬性彩掐。
4.4 小結:
1.基本類型值在內存中占據(jù)固定大小的空間,因此被保存在棧內存中灰追。
2.飲用類型的值是對象堵幽,保存在堆內存中。
第五章 引用類型
在JS中弹澎,引用類型是一種數(shù)據(jù)結構朴下,用于將數(shù)據(jù)和功能組織在一起。常被稱為類苦蒿。但它不具備傳統(tǒng)的面相對象語言所支持的類和接口等基本結構殴胧。
5.1 Object 類型
到目前為止,我們看到的大多數(shù)引用類型值都是object類型的實例佩迟。
var person=new Object();
person.name="nicho";
person.age=29;
另一種是使用對象字面量表示法团滥,簡寫形式,目的在于簡化創(chuàng)建包含大量屬性的對象报强。
var person={
name:"nico",
age:29,
5:true //5回自動轉換成字符串
};
可以為空:
var person={}; //花括號代表對象灸姊。()代表數(shù)組。
可使用對象字面量向函數(shù)傳遞大量可選參數(shù)的首選方式秉溉。
function displayInfo(args){
var output="";
if(typeof args.name=="string"){
output+=args.name;
}
}
displayInfo({
name:"nico",
age:29
});
訪問屬性: person["name"] person.name;
第一種方括號語法的優(yōu)勢是通過變量名訪問力惯、易出錯的屬性名訪問:
var pro="name";
person[pro];
person["first name"] //有空格
5.2 Array類型
在JS中碗誉,數(shù)組每一項能夠裝任何數(shù)據(jù)類型。如:第一個裝數(shù)組父晶,第二個裝對象诗充。
并且自動增加數(shù)組大小。
var colors=new Array();
var colors=new Array(20);
var colors=new Array("hello","wolrd",50);
var colors=Array();
//數(shù)組字面量法诱建。
var colors=[]; //方括號是數(shù)組蝴蜓,花括號是對象
var colors=[“world”,123];
數(shù)組的索引值很有意思俺猿。如果超出現(xiàn)有l(wèi)engh茎匠,會自動增加到該索引值加1.
lengh 的值是可以改變的,增加這個值押袍,改變數(shù)組大小诵冒。(增大或減小)
var colors=['red','blue'];
colors[colors.length]='black'; //在位置2添加谊惭,
colors[colors.length]='brown‘汽馋; //在位置3添加。
5.2.1 檢測數(shù)組
if(value instanceof Array){
}
但是instanceof有問題的是圈盔,如果網(wǎng)頁有多個框架豹芯,兩個框架間傳遞值,可能Array構造函數(shù)不同驱敲。
更好的辦法是: Array.isArray();
if(Array.isArray(value)) //php中是 is_array(value);
5.2.2 轉換方法
var colors=['red','blue'];
alert(colors.toString()); //red,blue 這個方法以逗號分隔字符串铁蹈。
alert(colors.valueOf()); //red,blue 返回數(shù)組,后調用toString
alert(colors) //red,blue 因為調用alert众眨,會后臺調用toString
alert(colors.join(',')) //red,blue
alert(colors.join('||')) //red||blue
5.2.3 棧方法
jS提供了讓數(shù)組類似于棧的行為握牧。 后進先出。 push\pop
var colors=new Array();
var count=colors.push("red","black"); //返回數(shù)組長度
alert(count); //2
count=colors.push("blk");
alert(count); //3
var item=colors.pop();
alert(item); //blk
alert(colors.length); //2
5.2.4 隊列方法
先進先出 push \shift
var colors=new Array();
var count=colors.push("red","black"); //返回數(shù)組長度
alert(count); //2
count=colors.push("blk");
alert(count); //3
var item=colors.shift();
alert(item); //"red"
alert(colors.length); //2
unshift():它能在數(shù)組前端添加任意個項并返回新數(shù)組的長度
pop():從數(shù)組后端取出數(shù)據(jù)娩梨。
這模擬了反向隊列沿腰。
var colors=new Array();
var count=colors.push("red","black");
alert(count); //2
count=colors.unshift("green"); green red black
alert(count); //3
var item=colors.pop();
alert(item); //"black"
alert(colors.length); //2
5.2.5 重排序方法:
reverse(): 反轉數(shù)組項的順序
sort():默認會為每個數(shù)組項調用toString()方法,之后對字符串進行比較狈定。
var values=[0,1,5,10,15];
values.sort();
alert(values); //0,1,10,15,5
sort()可以接受一個比較函數(shù):
function compare()
sort(compare); //和java中的排序樹類似颂龙。
5.2.6 操作方法
concat() 無參,只是復制副本掸冤,返回新數(shù)組
有參厘托,復制,若第二個參數(shù)為數(shù)組稿湿,每一項添加到副本中铅匹,若不是,簡單添加饺藤。
slice() 它能夠基于當前數(shù)組中的一個或多個項創(chuàng)建一個新數(shù)組包斑。
返回從初始位置到結束位置之間的項流礁。
splice() 主要用途向數(shù)組的中部插入項
1.刪除 splice(index,length) splice(0,2)
2.插入多個項 splice(index,length,value1,value2...) splice(2,0,value,value2)
3.替換 splice(2,1,value,value2)
返回一個數(shù)組,該數(shù)組中包含從原始數(shù)組中刪除的項
var colors=["red","green","blue"];
var remove=colors.splice(0,1);
alert(colors); //greem blue
alert(removed); //red
var remove=colors.splice(1,0,"yellow","orange");
alert(colors); //green yello orange blue
alert(removed); //空數(shù)組
var remove=colors.splice(1,1,"red","purple");
alert(colors); //green red purple orange blue
alert(removed); //yellow
5.27 位置方法
indexOf(searchString)\lastIndexOf(searchString).
要查找的項在數(shù)組中的的位置罗丰。
都是嚴格查找神帅,使用===.
var numbers=[1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(4)); //3
alert(number.lastIndexOf(4)); //5
alert(numbers.indexOf(4,4)); //5, 從4開始往后查找。
alert(number.lastIndexOf(4,4)); //3 從位置4開始從后往前查萌抵。
var person={name:"nice"};
var people=[{name:"nice"}];
var morePeople=[person];
alert(people.indexOf(person)); //-1 person和people不是一個對象
alert(morePeople.indexOf(person)); //0
5.2.8 迭代方法
5個方法:每個方法都接受兩個參數(shù):要在每一項上運行的函數(shù)和運行該函數(shù)的作用域對象——影響this的值找御。
every(): 如果該函數(shù)每一項都返回true,則返回true
filter(): 返回true的項組成的數(shù)組
forEach(): 無返回值
map() 返回每次函數(shù)調用的結果組成的數(shù)組绍填。
some(): 如果該函數(shù)的任一項返回true,則返回true霎桅。
every()和some()比較:
var numbers=[1,2,3,4,5,4,3,2,1];
var everyResult=numbers.every(function(item,index,array){
return (item>2);
});
alert(everyResult); //false
var someResult=numbers.some(function(item,index,array){
return (item>2);
});
alert(someResult); //true
filter():過濾函數(shù),通過函數(shù)讨永,篩選出符合條件的項滔驶。
var numbers=[1,2,3,4,5,4,3,2,1];
var filterResult=numbers.filter(function(item,index,array){
return (item>2);
});
alert(filterResult); //[3,4,5,4,3]
map():返回函數(shù)運行的結果
var numbers=[1,2,3,4,5,4,3,2,1];
var mapResult=numbers.map(function(item,index,array){
return (item*2);
});
alert(filterResult); //[2,4,6,8,10,8,6,4,2]
foreEach():和for循環(huán)沒什么區(qū)別,
5.2.9 縮小方法
reduce()\reduceRight() 從頭到尾|從尾到頭
迭代所有的項卿闹,然后構件一個最終返回的值揭糕。
reduce(): 他的第一個參數(shù)是前一項的函數(shù)運行的結果
var values=[1,2,3,4,5];
var sum=values.reduce(function(prev,cur,index,array){
return prev+cur;
});
alert(sum); //15
5.3 Date類型
var now=new Date(); //自動獲取當前日期和時間。
兩個方法幫助創(chuàng)建日期對象:Date.parse()和Data.UTC(); 都是格林尼治時間
Date.parse():
var someDate=new Date(Date.parse("May 25,2004"));
等價于
var someDate=new Date("May 25,2004"); //自動調用Date.parse():
Data.UTC(): 使用不同的參數(shù)锻霎,其他沒什么不同
//2000年1月1日0點0分
var y2k=new Date(Date.UTC(2000,0));
//2005.5.5,17:55:55
var allfiv= new Date(Date.UTC(2005,4,5,17,55,55)); //月著角、小時從0計數(shù)
本地時間:
var data=new Date(2000,5);
Date.now() 返回此時的毫秒數(shù)。
5.3.1 繼承的方法
5.4 RegExp類型
var expression=/pattern/flags;
flag: g: 全局模式量窘,即搜索全局雇寇,才返回,而不是查找到第一個就返回
i :不區(qū)分大小寫
m:表示多行蚌铜,即在一行文本末尾是否會繼續(xù)查找下一行。
字面量形式:
var pattern1=/at/g; //查找包含at的所有
var pattern2=/[bc]at/i; //查找bat或cat的匹配項嫩海,不區(qū)分大小寫
var pattern3=/.at/gi; //查找所有以at結尾的三個字符的組合冬殃,不區(qū)分大小寫
//這里的.不是元字符,指的是任意一個字符叁怪。想要表示.审葬,需要轉義
所有的元字符必須轉義。有:
([{ \ ^ $ | ) ? * + . ] }
如:
var pattern2=/\[bc\]at/i; 匹配第一個“[bc]at”奕谭,不區(qū)分大小寫涣觉。
var pattern3=/\.at/gi; 查找所有以".at"的組合,不區(qū)分大小寫
構造函數(shù)方式:
var pattern2=new RegExp("[bc]at","i");
//注意:這里傳入的字符串血柳,那么想要使用特殊的字符就需要雙重轉義官册,才能變成字面量的模式。
字面量模式 等價的字符串
/\[bc\]at/ “\\[bc\\]at”
\.at "\\.at"
\w\\hello\\123 "w\\\\hello\\\\123"
var re =null,i;
for(i=0;i<10;i++){
re=/cat/g;
re.test("catastrophe");
}
for(i=0;i<10;i++){
re=new RegExp("cat","g");
re.test("catastrophe");
}
第一種难捌,實際上只產生了一個RegExp實例膝宁。由于實例屬性不會重置,第二次會從索引值為3的字符開始的鸦难。
而使用構造函數(shù),則每次會創(chuàng)建新的實例员淫。
5.4.1 RegExp 實例屬性
global: 是否設置g標志合蔽。
ignoreCase:是否設置i標志。
lastIndex: 表示開始搜索下一個匹配項的字符位置介返。
multiline:是否設置了m標志
source:正則表達式字符串表示拴事,會返回字面量形式。
5.4.2 RegExp 實例方法
RegExp對象的主要方法是exec()圣蝎。
使用全局變量g后挤聘,執(zhí)行exec()函數(shù)會返回字符串中的下一個匹配項,直到末尾捅彻。
var text="cat,bat,sat,fat";
var pattern1=/.at/;
var match=pattern1.exec(text);
alert(matches.index); //0
alert(matches[0]); //cat
alert(pattern1.lastIndex); //0
var match=pattern1.exec(text);
alert(matches.index); //0
alert(matches[0]); //cat
alert(pattern1.lastIndex); //0
var pattern2=/.at/g;
var match=pattern2.exec(text);
alert(matches.index); //0
alert(matches[0]); //cat
alert(pattern2.lastIndex); //0
var match=pattern2.exec(text);
alert(matches.index); //5
alert(matches[0]); //bat
alert(pattern2.lastIndex); //8
text() :傳一個參數(shù)组去,判斷目標字符串與某個模式是否匹配。 true\false步淹。
RegExp 繼承的toString()方法都會返回正則表達式的字面量从隆。
var pattern=new RegExp("\\[bc\\]at","gi");
alert(pattern.toString()); // /\[bc\]at/gi
5.4.3 RegExp 構造函數(shù)屬性
通過RegExp可以查看到最近一次正則表達式操作。
var text="this has been a short summer.";
var pattern=/(.)hort/g;
if(pattern.test(text)){
alert(RegExp.input); //this has been a short summer
alert(RegExp.leftContext); //this has been a
alert(RegExp.rightContext); //summer.
alert(RegExp.lastMatch); //short
alert(RegExp.lastParen); //s
alert(RegExp.multiline); //false
}
5.5 Function 類型
函數(shù)實際上是對象缭裆,每個函數(shù)都是Function類型的實例键闺。
function sum(num1,num2){}
等價于
var sum= function(num1,num2){};
在函數(shù)中,函數(shù)名僅僅是指向函數(shù)的指針澈驼,可以多次賦值辛燥。
5.5.1 沒有重載
function addSomeNumber(num){
return num+100;
}
function addSomeNumber(num){
return num+200;
}
var result=addSomeNumber(100); //300
聲明了同名函數(shù),但其實后面的覆蓋前面的缝其。
5.5.2 函數(shù)聲明與函數(shù)表達式
解析器會執(zhí)行任何代碼之前優(yōu)先解析函數(shù)聲明挎塌,而函數(shù)表達式只會在運行到此行才解析。
alert(sum(10,10));
function sum(){}
完全可以正常運行内边。
5.5.3 作為值的函數(shù)
可以將函數(shù)作為值傳給函數(shù)榴都。
function A(someFunction,someArgument){
return someFunction(someArgument);
}
也可以從一個函數(shù)中返回另一個函數(shù)。
function createFunction(propertyName){
return function(object1,object2){
var value1=object1[propertyName];
var value2=object1[propertyName];
if(value1>value2)
...
...
...
}
}
var data=[{name:"zhang",age:20},{name:"li",age:21}];
data.sort(createFunction("name"));
5.5.4 函數(shù)內部屬性
在函數(shù)內部漠其,有兩個特殊的對象:arguments和this.
arguments的callee屬性嘴高,指向擁有這個arguments對象的函數(shù)。如階乘:
function sum(num){
if(num<=1){
return 1;
}else{
return num*arguments.callees(num-1);
}
}
this引用的是函數(shù)已執(zhí)行的環(huán)境對象和屎。(誰調用它拴驮,誰就是this.)
caller. 這個屬性保存著調用當前函數(shù)的函數(shù)的引用。
function outer(){
inner();
}
function inner(){
alert(arguments.callee.caller);
}
outer();
它會顯示outer的源代碼柴信。因為outer()調用了inter()套啤,所以caller指向outer()..
5.5.5 函數(shù)屬性和方法
函數(shù)是一個對象,既然是對象颠印,就有屬性和方法纲岭。屬性: length和prototype
length 代表函數(shù)想要接受的參數(shù)的個數(shù)
function sayName(name){}
function sayHi(name1,nam2){}
alert(sayName.length) //1
alert(sayHi.length) //2
prototype 是保存引用類型所有實例方法的真正所在抹竹。即:toString()\valueOf()等方法都保存在prototype
名下。
每個對象都包含兩個非繼承而來的方法:apply()\call().
用途都是在特定的作用域中調用函數(shù)止潮,實際上等于設置函數(shù)體內this對象的值窃判。
apply()傳入?yún)?shù)數(shù)組。
function sum(num1,num2){}
function callSum1(num1,num2){
return sum.apply(this,arguments);
}
function callSum1(num1,num2){
return sum.apply(this,[num1,num2]);
}
alert(callSum1(10,10)); //20
alert(callSum2(10,10)); //20
解釋:this喇闸,指代的誰調用的它袄琳,這里是window對象,那么就變成了window.sum(10,10);
call要傳入每個參數(shù)燃乍。
function sum(num1,num2){}
function callSum1(num1,num2){
return sum.call(this,[num1,num2]);
}
alert(callSum1(10,10)); //20
來個復雜的例子:
function baseClass()
{
this.showMsg = function()
{
alert("baseClass::showMsg");
}
}
function extendClass()
{
this.showMsg =function ()
{
alert("extendClass::showMsg");
}
}
如果我想使用extendClass的一個實例instance調用baseClass的對象方法showMsg怎么辦唆樊?
extendClass.prototype = new baseClass();
var instance = new extendClass();
var baseinstance = new baseClass();
baseinstance.showMsg.call(instance);//顯示baseClass::showMsg
這句話的意思就是:使用instance是調用者,調用他方法中和baseinstance.showMsg相同的方法刻蟹。
apply()和call()的真正用武之地就是:擴充函數(shù)賴以運行的作用域逗旁。
window.color="red";
var o={color:"blue"};
function sayColor(){ alert(this.color);}
sayColor.call(this); //red
sayColor.call(window); //red
sayColor.call(o); //red
使用call和apply()方法最大的好處就是降低耦合, 我們不需要在對象中定義方法舆瘪,當對象需要方法時片效,直接
讓這個方法.call(對象)即可。
bind()方法:會闖一個函數(shù)的實例英古,其this值會被綁定到傳給bind()函數(shù)的值淀衣。
window.color="red";
var o={color:"blue"};
function sayColor(){ alert(this.color);}
var objectSayColor=sayColor.bind(o);
objectSayColor(); //blue
5.6 基本包裝類型
為了便于操作基本類型值,還提供了3個特殊的引用類型:Boolean\Number和String召调。
實際上膨桥,每當讀取一個基本類型,后臺會創(chuàng)建一個對應的基本包裝類型的對象,能夠調用一些方法操作這些數(shù)據(jù)唠叛。
eg: var s1="some text";
var s2=s1.substring(2);
基本包裝類型和引用類型的區(qū)別主要在生存期只嚣。基本包裝類型的生存期在執(zhí)行完即銷毀玻墅,而引用類型是一直保存在內存中的介牙。
eg:
var s1="some text";
s1.color="red"; //當代碼執(zhí)行到這行時,創(chuàng)建實例對象澳厢,調用指定方法或屬性,銷毀囚似。
alert(s.color); //undefined
5.6.1 Boolean類型: 不推薦使用蜒蕾。
Boolean類型的實例重寫了valueOf()方法粟按,返回基本類型值true和false.toString 返回字符串"true"和“false”
var falseObject=new Boolean(false);
var result=falseObject && true;
alert(result); //true
var falseValue=false;
result=falseValue && true;
alert(result); //false
第一個創(chuàng)建了一個對象,在布爾表達式中的所有對象都會被轉換為true,因此結果為true。
alert(typeof falseObject); //object
alert(typeof falseValue) ; //Boolean
alert(falseObject instanceof Boolean); true
alert(falseValue instanceof Boolean ); false
typeof對基本類型返回Boolean. 對引用類型返回object.
由于Boolean對象是Boolean類型的實例偶宫,所以為true.
5.6.2 Number 類型
Number 類型重寫了valueOf()\toString等方法。
var number =10;
alert(num.toString(2)); //"1010"
toString()方法加參數(shù),可以轉換進制。
還提供了一些用于將數(shù)值格式化為字符串的方法
toFixed():按照指定小數(shù)位返回數(shù)值的字符串表示角雷。 適用于貨幣值。
var num=10;
alert(num.toFixed(2)); //"10.00"
如果本身包含的小數(shù)位比指定的還多性穿。那么指定的最后一位舍入勺三。
var num=10.005;
alert(num.toFixed(2));"10.01"
toExponential():返回以指數(shù)表示法表示的數(shù)值的字符串形式。
var num=10;
alert(num.toExponential(1)); //1.0e+1
toPrecision():會根據(jù)規(guī)則看哪個表示合適返回值需曾。接受一個函數(shù)吗坚,即表示數(shù)值的所有
位數(shù)。
var num=99;
alert(num.toPrecision(1)); //1e+2
alert(num.toPrecision(2)); //"99"
alert(num.toPrecision(3)); //"99.0"
5.6.3 String 類型
1.字符方法
charAt()和charCodeAt()呆万。一個返回給定位置的字符商源,一個返回給定位置的字符編碼。
var stringValue="hello world".
alert(stringValue.chartAt(1));"e"
alert(stringValue.chartCodeAt(1));"101"
alert(stringValue[1]); //"e" 也可以使用這種方式訪問谋减。
2.字符串操作方法
concat():將一或多個字符串拼接起來牡彻。
var stringValue="hello ";
var result=stringValue.concat("world");
alert(result); //"hello world"
var result=stringValue.concat("world","!"); //可拼接多個。
alert(result); //"hello world !"
slice()\substr()和substring():三個都是字符切割函數(shù)出爹。
var stringValue="hello world";
alert(stringValue.slice(3)); //"lo world"
alert(stringValue.substring(3)); //"lo world"
alert(stringValue.substr(3)); //"lo world"
alert(stringValue.slice(3,7)); //"lo w"
alert(stringValue.substring(3,7)); //"lo w"
alert(stringValue.substr(3,7)); //"lo worl"
//substr第二個參數(shù)是返回字符個數(shù)
3.字符串位置方法
indexOf()和lastIndexOf().這兩個方法都是從一個字符串中搜索給定的子字符串庄吼,返回
返回位置,如果沒有返回-1.一個從前以政,一個從后霸褒。
第一個參數(shù)是字符串,第二個參數(shù)是搜索起始位置盈蛮。
4.trim()方法
創(chuàng)建一個字符串副本废菱,刪除前置及后綴的所有空格,然后返回結果抖誉。
5.字符串大小寫轉換方法
toLowerCase()殊轴、toUpperCase().
6.字符串的模式匹配方法
match():只接受一個參數(shù),要么正則表達式袒炉,要么是一個RegExp對象旁理。
var text="cat,bat,sat,fat";
var pattern=/.at/;
var matches=text.match(pattern);
alert(matches.index);
search():一個參數(shù),字符串或RegExp對象指定的一個正則表達式我磁。
replace()方法:
var text="cat,bat,sat,fat";
var result=text.replace("at","ond");
alert(result); //"crond"
字符序列
result=text.replace(/.at/g,"word ($1)");
alert(result); //word (cat),word (bat),word (sat),word (fat)
第二個參數(shù)為函數(shù)
text.replace(/[<>"&]/g,function(match,pos,originalText){
switch(match){
}
})
var colorText="red,blue,green,yellow";
var color1=colorText.split(",");
var color2=colorText.split(/[^\,]+/);
7.localeCompare()
比較:規(guī)則就是前面的減去后面的
var stringValue="yellow";
alert(stringValue.localeCompare("brick")); //1
alert(stringValue.localeCompare("zoo")); //-1
8.fromCharCode()方法
接受字符編碼孽文,轉換成字符出阿妹。
5.7 單體內置對象
由ECMAScript實現(xiàn)提供的夺艰、不依賴于宿主環(huán)境的對象芋哭,這些對象在ECMAScript程序執(zhí)行前就已經(jīng)存在了。
如:Oject|Array|String|Global|Math
5.7.1 Global對象
不屬于任何其他對象的屬性和方法郁副,最終都是它的屬性和方法减牺。
1.URI編碼方法(URI:uniform Resource Identifiers 通用資源標識符,是更高層次的URL)
Global對象的encodeURI()和encodeURIComponent()方法可以對URI進行編碼。
encodeURI:用于整個URI拔疚,只對空格編碼.這個作用于URL跳轉的時候肥隆。
和encodeURIComponent():對任何非標準字符進行編碼。 使用它稚失,傳遞一個長的url不會被截斷栋艳。
2.eval()方法 ==>能夠解釋代碼字符串。
像是一個完整的ECMAScirpt解析器墩虹。只接受一個參數(shù)嘱巾,即要執(zhí)行的ECMAScript字符串。
eval("alert('hi')"); === alert("hi");
當解析器發(fā)現(xiàn)代碼中調用eval方法時诫钓,他會將傳入的參數(shù)當作實際的ECMAScript語句來解析旬昭,然后把執(zhí)行結果插入到原位置。通過eval()
執(zhí)行的代碼被認為是包含該次調用的執(zhí)行環(huán)境的一部分菌湃,因此被執(zhí)行的代碼具有與該執(zhí)行環(huán)境相同的作用鏈问拘。
var msg="hello world";
eval("alert(msg)"); //hello world
eg2:
eval("fucntion sayHi(){alert("123")}");
sayHi();
3。Global 對象的屬性
4.window 對象
瀏覽器將Global對象作為window對象的一部分加以實現(xiàn)惧所。
可以取得Global對象的方法:
var global=function(){return this}();
5.7.2 Math對象
min()和max()方法
var max=Math.max(3,4,5,6123,15);
這種避免多余循環(huán)和if語句來檢驗最大值骤坐。
要找到數(shù)組中最大最小值,使用apply();
var values=[1,2,3,45,67,4,];
var max=Math.max.apply(Math,values); //這里關鍵是Math作為第一個參數(shù)下愈,正確設置了this值纽绍。
舍入方法: Math.ceil()\Math.floor()\Math.round()
4.random()方法
var num=Math.floor(Math.random()*10+1);