您好,登錄后才能下訂單哦!
1 JavaScript 簡稱JS,是一種動態的弱類型腳本解釋型語言,和HTML,CSS并成為三大WEB核心技術,得到了幾乎所有主流瀏覽器的支持
1994年,網景Netscape公司成立并發布了Netscape navigator瀏覽器,占據了很大的時長份額,網景意識到WEB需要動態,需要一種技術來實現
1995年9月網景瀏覽器2發布測試版本發布了livescript,隨即在12月的測試版就更名為JavaScript,同時期,微軟推出IE并支持JScript,VBScript。
1997年,網景,微軟,SUN,borland公司和其他組織在ECMA確定了ECMAscript語言標準,JS則是ECMAscript的標準實現之一。
由于IE的捆綁銷售行為,網景的單一瀏覽器時長萎縮,從1990年的90%下降到2006年的1%,1999年網景被AOL收購,收購不就,netspace公開了瀏覽器代碼,并創建了Mozilla組織,Mozilla組織使用Gelo引擎重寫瀏覽器,當然Mozilla將Geko引擎發布了Firefox瀏覽器
2003年5月,網景被解散
AOL于2007年宣布停止支持Netscape瀏覽器
HTTP cookie ,解決HTTP無狀態
JavaScript
ssl協議
jar 格式文件,將Java的class文件打包,并加上簽名
2012年4月9日,微軟以10億5千6百萬購買800向美國在線的專利或專利授權,并收購了SSL,cookie等專利。
ES,ECMAScript是由ECMA國際(前身為歐洲計算機制造協會,英文名稱是European Computer Manufactures Association)通過ECMA-262標準化的腳本程序設計語言,該語言被廣泛應用于互聯網
JavaScript是商品名,目前商標權在Oracle公司手中,ES是標準名。
根據ES標準,有很多實現引擎,其中包括JavaScript或JScript,他們都是ECMA-262標準的實現和擴展。
1997年,制定了首個ECMA-262
1999年12月,EC3,支持更強大的正則表達式
ES4 太過激進,最終被放棄
2009年,ES5發布,得到廣泛支持,支持嚴格模式,支持Json
2015年,ES6發布,引入非常多的新的語言特性,還兼容舊版本的特性,ES6之前按照版本號命名,從ES6開始使用年份作為版本號,ES6 及ECMAscript 2015.
運行HTML,CSS,JS技術都在發展,標準版本很多,瀏覽器內嵌的引擎實現不太一致,甚至有不按照標準實現,或者減少實現,或者改變實現,或者增加的功能,如IE,就導致了開發人員負擔,很難做到一套代碼可以兼容的跑在多種瀏覽器中,甚至不能跑在同一種瀏覽器的不同版本中。
就在瀏覽器IE一家獨大時,Firefox和Chrome開始變強
2008年9月2日,Google的Chrome瀏覽器發布,一并發布的js引擎,就是V8引擎,V8使用BSD協議開源
V8引擎支持C++開發,將JavaScript編譯成了機器碼,而不是字節碼,還是用很多優化方式提高性能,因此,V8引擎速度很快。
V8 引擎還可以獨立運行,可以嵌入到其他任何C++程序中。
V8 引擎的誕生,使得服務器端運行JS稱為了方便的事情。
nodejs是服務器端運行JavaScript的開源的,跨平臺的運行環境
nodejs原始作者瑞安達爾于2009年發布,使用了V8引擎,并采用事件驅動,非阻塞異步IO模型
2010年,npm軟件包管理器誕生,通過它,可以方便的發布,分析nodejs的庫和源代碼。
nodejs4.0引入了ES6的語言特性。
需要安裝nodejs和visual studio code
相關下載nodejs
https://npm.taobao.org/mirrors/node/v12.10.0/node-v12.10.0-x64.msi
visual studio code
https://vscode.cdn.azure.cn/stable/b37e54c98e1a74ba89e03073e5a3761284e3ffb0/VSCodeUserSetup-x64-1.38.1.exe
插件NodeExec和漢化包安裝
重新啟動軟件即可生效,
和C 、Java一樣
//單行注釋
/*注釋*/多行注釋,也可以使用在語句中
注: 使用快捷鍵F8運行代碼,其代碼必須是已經保存的文件,不能是空,F8可能和有道詞典快捷鍵沖突,建議在此運行期間不運行有道詞典。
1 標識符
標識符必須是字母,下滑線,美元符號和數字,但必須是字母,下劃線,美元符號開頭,依然不能是數字開頭
標識符區分大小寫
2 標識符的聲明
var 聲明一個變量
let 聲明一個塊作用域中的局部變量
const 聲明一個常量JS中的變量聲明和初始化時可以分開的
常量的存放位置和變量是不在一起的
console.log(a) // 后面聲明的變量,前面可以使用,但沒意義
var a //只是聲明,并未賦值,其類型是undefined,
let b //聲明為塊變量
console.log(1,a,b) //打印
a=1 //變量賦值,不規范化操作,不推薦,在嚴格模式下回導致異常。在賦值之前不能引用,因為未為進行聲明,其賦值的結果是全局作用域
b='123'
console.log(2,a,b)
const c=100 //定義常量
console.log(c)
var d=10 //規范聲明并初始化
console.log(3,d)
c=200 //修改常量值,不可修改,因為其是常量
console.log(4,c)
結果如下
常量和變量的選擇
如果明確知道一個標識符定以后便不再改變,應該盡量聲明成const常量,減少被修改的風險,減少bug。
function test(){
var x=10; //聲明并初始化x
y=20; //聲明vi能夠初始化y
console.log(x,y)
}
test()
console.log(x,y) //此處在函數中,其所有參數皆不能沖破作用域
// x=100
// console.log(x)
結果如下
函數本身天生就是一個作用域
其實就是將聲明定義到最前面罷了,及就是先調用,再定義
console.log(a)
console.log(b)
console.log(c)
console.log(d)
console.log(e)
var a=200; // 提升作用域,只有var定義變量的方式可以提升作用域
var b;
const c=300; //此處不能提升作用域
let d;
e=300;
結果如下
序號 | 名稱 | 說明 |
---|---|---|
1 | number | 數值型,包括整數類型和浮點型 |
2 | boolean | 布爾型,true和false |
3 | string | 字符串 |
4 | null | 只有一個值null |
5 | undefined | 變量聲明未賦值的,對象未定義的屬性 |
6 | symbol | ES6新引入的類型 |
7 | object類型 | 是以上基本類型的復合類型,是容器 |
ES是動態語言,弱類型語言
雖然先聲明了變量,但是變量可以重新賦值成任何類型
console.log(a=1+'test',typeof(a)) // typeof:打印類型
console.log(a=false+'test',typeof(a)) //和布爾類型運算
console.log(a=null+'test',typeof(a)) //和null比較
console.log(a=true+'test',typeof(a))
console.log(a=undefined+'test',typeof(a)) //和數字
結果如下
console.log(a=1+false,typeof(a))
console.log(a=1+true,typeof(a))
console.log(a=1+null,typeof(a))
console.log(a=1+undefined,typeof(a))
結果如下
console.log(a=false+undefined,typeof(a))
console.log(a=true+undefined,typeof(a))
console.log(a=false+null,typeof(a))
console.log(a=true+null,typeof(a))
console.log(a=true & '',typeof(a)) //位運算
console.log(a=undefined && true,typeof(a)) //與運算
True是透明的,false則直接就是短路,返回直接就是false,類型是布爾。true主要是看后面的情況
console.log(a=false??&&?null,typeof(a)) //如果前面是false,則返回結果是false,且類型是布爾類型
console.log(a=false??&&??'zhangbing',typeof(a))
console.log(a=true??&&?'32534534',typeof(a)) //如果前面是true,則以后面為準
console.log(a=true??&&?''?,typeof(a))
弱類型,不需要強制轉換
NaN,Not a Number,轉換數字失敗
遇到字符串,加括號就是拼接字符串,所有非字符串隱式轉換為字符串
如果沒有字符串,加號把其他所有類型都當數字處理,非數字類型隱式轉換成數字,undefined特殊,因為它都沒有定義值,所有其是一個特殊的數字Nan。
如果運算符是邏輯運算符,短路符,則返回就是短路時的類型,沒有隱式轉換
除非你十分明確,否則不要依賴隱式類型轉換,寫代碼時,往往為了程序的健壯性,建議顯式轉換
將一個值一單引號或雙引號引用后便形成了字符串
let a="a\"aaaaaa" // 可使用轉義符號
let b='adadsaasd' //單引號定義
let c="asfsdfsadfsdf'sdfsdfsdfsdf'" //混合定義
let d=`'abcd'` //反引號定義
let e=`x= ${a} y=${b}` //插值,類似于Java中的替換和python中的format
console.log(a,b,c,d)
console.log(e)
結果如下
字符 | 說明 |
---|---|
\0 | Null 字節 |
\b | 退格符 |
\f | 換頁符 |
\n | 換行符 |
\r | 回車符 |
\t | Tab(制表符) |
\v | 垂直制表符 |
' | 單引號 |
" | 雙引號 |
|反斜杠字符() | |
\XXX | 由從0到377最多三個八進制數XXX表示的Latin-1字符 |
\xXX | 由從00和FF的兩位十六進制數字XX表示的Latin-1字符 |
\uXXXX | 由4位十六進制數字XXXX表示的Unicode字符,例如,\u00A9是版權符號的Unicode序列,見Unicode escape sequence |
\u{xxxxxx} | Unicode代碼點(code point)轉義字符 |
支持索引,切片,查詢,替換和鏈接
console.log('adasddasdasd'.indexOf(1)) //查找位置,若不存在,則返回-1
console.log('abced'.indexOf('c')) //獲取對應位置
console.log('12345'.charAt(4)) //索引獲取元素
console.log('1234'.concat('666')) // 元素追加
const a='123456' //定義一個常量
console.log(a[3]) //通過索引獲取元素
console.log(a.toUpperCase()) //大寫轉換
console.log(a.slice(1,3)) //切片,左閉右開 1,2處的元素
console.log(a.slice(-3,-1)) //45
const url=' www.baidu.com '
console.log(url.split('.')) //字符串分割
console.log(url.startsWith('www')) //匹配字符串起始,返回false或true
console.log(url.substr(3,6)) //從索引為3開始6個字符
console.log(url.substr(3,6)) //從索引為3開始到索引為6結束
console.log(url.replace('com','edu')) //字符串一替換
console.log(url.trim()) //取出兩邊的空白字符
進制符 | 描述 |
---|---|
0bxxx/0Bxxx | 二進制 |
0oxxx | 八進制 |
0xxxx | 十六進制 |
在JS中,數據均為雙精度浮點型范圍只能在-(2^53-1)和2^53-1之間,整數類型也不例外,數字類型還有三種符號值:+Infinity(正無窮),-Infinity(負無窮)和Nan(not-a-number非數字)
二進制0b0010,0B100.
八進制0755,注意0855,將被認作是十進制,因為8不在八進制中,ES6中最好使用0o 前綴表示八進制
十六進制0xAA,0xff
指數表示1E3(1000),2e-2(0.02)
常量屬性
var biggestNum=Number.MAX_VALUE; //最大值
var smallestNum=Number.MIN_VALUE; //最小的大于0的數
var infiniteNum=Number.POSITIVE_INFINITY;
var negInfiniteNum=Number.NEGATIVE_INFINITY;
var notANum=Number.NaN;
數字方法
方法 | 描述 |
---|---|
Number.paraseFloat() | 把字符串參數解析成浮點數,和全局方法parseFloat()作用一樣 |
Number.parseLnt() | 把字符串解析成特定基數對應的整數類型數字,和全局方法parseInt()作用一致 |
Number.isFinite() | 判斷傳遞的值是否為有限數字 |
Number.isInteger() | 判斷傳遞的值是否為整數 |
Number.isNaN() | 判斷傳遞的值是否是NaN |
內置數學對象Math
Math提供了絕對值,對數指數運算,三角函數運算,最大值,最小值,隨機數,開方等運算函數,提供了P|值
console.log(typeof(parseInt('1234123423423')),'134234') //轉換為數值類型
console.log(isNaN(10)) //判斷是否為NaN
console.log(isFinite(10/3))
console.log(Math.abs(-1)) //絕對值
console.log(Math.random()*1000) //生成隨機數
符號 | 描述 |
---|---|
+ | 加 |
- | 減 |
* | 乘 |
/ | 除 |
% | 余 |
++i | 單目運算符先加后賦值 |
i++ | 單目運算符先賦值后加 |
--i | 單目運算符先減后賦值 |
i-- | 單目運算符先賦值后減 |
單目運算符,自增和自減只針對一個參數的運算符
++ 和 --
i++ 表示先用,后加,其加的值為1
++i 表示先加,后用,其加的值也是1
總之,誰在左,誰先執行
反之--也是亦然。
let i=0;
a=i++ //此處是先用后加,因此其a的值應該是0,之后加1
console.log(a)
b=++i; //此處是先加后用,此處的b的值應該是i為1的基礎是加1,及為2
console.log(b)
c=i++; //此處是先用,及c為2
console.log(c)
結果如下
其中單目運算符的優先級高于雙目運算符。
相關習題
let i=0;
a=(++i+i+++i+++i)
//其中單目優先級高,則可拆解為 ++i + i++ + i++ +i
//++i結果為1 ,i++結果i為1 i++ 結果i為2 i的結果為3 最終為1+1+2+3=7
console.log(a)
結果如下
此題主要考慮兩個點
1 單目運算符優先級高于雙目運算符
2 加號+是雙目運算符,兩邊的表達式必須先計算好
符號 | 描述 |
---|---|
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
!= | 不等于,寬松模式進行類型轉換 |
== | 寬松模式等于,及就是進行類型轉換 |
!== | 嚴格模式不等于,及不進行類型轉換 |
=== | 恒等,及全等,不進行類型轉換 |
console.log('1'==1) //此處為寬松模式,進行類型轉換,此處為true
console.log('1'===1) //此處為嚴格模式,此處返回為False
console.log('200'>300) //此處為true,進行了類型轉換
console.log('2a'<200) //此處為false,此處的2a是不能轉換為數字的,因此不能參與比較,因此其返回值為false
console.log(Number.MAX_VALUE>10000) //和最大比較,返回為true
console.log(Number.MIN_VALUE < 0.00001) //和最小比較,范圍為true
console.log(Number.MAX_VALUE>Number.MIN_VALUE) //最大和最小比較,返回為true
結果如下
Column 1 | Column 2 |
---|---|
&& | 邏輯與 |
|| | 邏輯或 |
! | 邏輯非 |
這些運算符和其他高級語言相同。支持短路。
方法 | 描述 |
---|---|
& | 位與 |
| | 位或 |
^ | 異或 |
~ | 取反 |
<< | 左移 |
>> | 右移 |
條件表達式?真值:假值,鄧建與簡單的if ...else 結構
console.log(('3'>30)?'真':'假')
console.log((4<5)?'假':'真')
JS 運行多個表達式寫在一起的情況
console.log(a,b,c)
var a=100,b=200,c=300 //提升作用域,會定義三個元素
結果如下
詳情見 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
名稱 | 說明 |
---|---|
Instanceof | 判斷是否屬于指定類型 |
typeof | 返回類型字符串 |
delete | delete操作符,刪除一個對象(an object)或者一個對象的屬性(an object's property) 或者一個數組中的某一個鍵值(an element at a specified index in an array)。 |
in | 如果指定的屬性在對象內,則返回true |
instanceof 要求必須明確使用類型定義變量,就是對象必須是new關鍵字聲明創建的,它可以用于繼承關系的判斷
typeof 就是返回對象的類型字符串
delete刪除對象,屬性,數組元素
a=new String('abcd')
b=new Number(123)
console.log(a instanceof String)
console.log(b instanceof Number)
console.log(typeof(a))
console.log(typeof(b))
console.log(typeof(100))
console.log('--------------delete-----------')
x=42
var?y=43
let??z=60
myobj=new?Number();
myobj.h=4??//增加屬性?
console.log(delete??x);??//隱式聲明使用delete能夠刪除成功
console.log(delete?y);??//var聲明的不能刪除
console.log(delete?z);?//let聲明的依然不能刪除
console.log(delete?myobj.PI)?//不能刪除預定義的對象,
console.log(delete?myobj.h)?//?自定義的屬性變量是可以刪除的
console.log(delete?myobj)??//自定義的對象可以刪除,因為其是隱式聲明,因此可以刪除
console.log('+++++++++++++++++++')
var??trees?=?new?Array('redwoord','bay','cendar','cak','maple')
for?(var??i=0;i<trees.length;i++)
????console.log(trees[i])
console.log('====================')
delete?trees[3];//刪除其中的元素,其數組不會少,只會在當前索引對應的數據變為undefined
for?(var??i=0;i<trees.length;i++)
????console.log(trees[i])
console.log('-------------object----------------')
let?mycar?={
????make:'Honda',
????model:'Accord',year:?2019
};
console.log('make'?in?mycar);??//true
console.log('model'?in?mycar);??//true??
結果如下
if (cond1) {
}
else if (cond2) {
}
else if (cond3) {
}
else {
}
條件為false的等效
false
undefined
null
0
NaN
空字符串其他的將均被視為True,如空列表。
if ([])
{
let d=4;//定義為塊變量,其不能穿透if
var e=5; //var 定義,能夠穿透if
f=6; //定義,能夠穿透
if (true) {
console.log(d);
console.log(e);
console.log(f);
g=10;
var h=11;
let t=13;//定義為塊變量,其不能穿透if
}
}
console.log(h,g,f)
console.log(t)
結果如下
switch (expression) {
case label_1:
statements_1
[break;]
case label_2:
statements_2
[break;]
...
default:
statements_def
[break;]
}
let a=3
switch (a) {
case 1:
console.log(1)
break;
case 2:
console.log(2)
break;
case 3:
console.log(3)
break;
default:
console.log(4)
break;
}
結果如下
switch的穿透效果,直到碰見break為止。
let a=3
switch (a) {
case 1:
console.log(1)
case 2:
console.log(2)
case 3:
console.log(3)
default:
console.log(4)
}
結果如下
//C風格for循環
for ([initialExpression];[condition];[incrementExpression])
{
statement
}
arr=[10,20,30]
for (let x=0;x<arr.length;x++){
console.log('i',arr[x])
}
console.log('+++++++++++++++++')
for (let j=0;j<arr.length;j++,j++) { //注意,此處是逗號(i++,i++)
console.log('j',arr[j])
}
// for (z=0;z<arr.length;) { // 此處是死循環,因為沒有增加條件
// console.log(arr[z])
// }
for (let a=0,b=200;a<arr.length;a++,b++) { // 多條件操作
console.log(a,arr[a],b);
}
for ( let z in arr) { //此處獲取到的是索引
console.log(z,arr[z])
}
for (let w of arr) { //此處獲取到的是值
console.log(w)
}
let obj={'a':1,'b':2,'c':3}
for (let x in obj) { //使用for循環處理對key的訪問
console.log('obj',x)
}
// for (let y of obj) { //此處不能實現,因為其不能迭代對象
// console.log(y)
// }
結果如下
注意:for in 循環返回的是索引或者key,需要間接訪問到值。
數組反正返回的是索引,C風格for循環操作較為便利
對象使用for in 可以遍歷其key,但不能使用for of 迭代對象,原因是of后面必須是一個迭代器,可類比python中的for in。
while 循環一般適用于死循環,while循環是先判斷,do...while循環是先執行,后判斷。
while (condition){
statement
}
do {
statement
}
while(condition)
先進入循環,然后判斷,為真就繼續循環
let x=10;
while (x--){
console.log(x)
}
結果如下
let x=10;
do {
console.log(x)
}while(x--)
結果如下
break 結束當前循環,直接退出這個循環體
continue 中斷當前循環,直接進入下一次循環,同一個循環中的某一個跳過練習
打印9*9乘法口訣
for (i=1;i<10;i++) {
line=" "
for (j=1;j<=i;j++){
line += `${j}*${i} = ${i*j} `
if (i==j)
console.log(line);
}
}
函數: 函數也是對象
格式如下
function 函數名(參數列表) {
函數體;
return 返回值;
}
示例如下
function add(x,y){
return x+y;
}
console.log(add(4,5))
結果如下
使用表達式來定義函數,表達式中的函數名可以省略,如果這個函數名不省略,也只能用于該函數的內部。
const add =function _add(x,y) {
return x+y;
}
console.log(_add(4,5))
結果如下
const add =function _add(x) {
if (x==1){
return x;
}
return _add(x-1)+x //遞歸調用,該函數只能在其內部被調用
}
console.log(add(10))
結果如下
const add =function (x,y) { //匿名函數
return x+y;
}
console.log(add(4,5))
console.log(show)
function show(){ //函數可以提升作用域
console.log('show')
}
console.log(add)
var add=function(){ //函數表達式則不能提升作用域
return 1;
}
結果如下
函數,匿名函數,函數表達式的差異
函數和匿名函數,本質上都是一樣的,都是函數對象,只不過函數有自己的標識符--函數名。匿名函數需要借助其他標識符而已。
區別在于,函數會聲明提升,函數表達式不會。
高階函數:參數為函數或返回值為函數的函數稱為高階函數
function a(){
console.log('a')
return function b(){
console.log('b')
return 'b' //函數必須有返回值,否則,返回為undefined
}
}
console.log(a()) //調用外層函數
console.log(a()()) //由于a返回值函數,因此可以使用括號來進行相關的調用操作
結果如下
let counter=function() {
let i=0;
function _fun(){
return ++i;
}
return _fun
}
c=counter()
console.log(c())
console.log(c())
console.log(c())
console.log(c())
結果如下
實現map函數的功能,傳入一個函數,傳入一個值,輸出一個值處理后的情況,如輸入1,2,3,4,輸出為1 4 9 16 及平方
const map1= function (fn,arr){
newarry=[];
for (i in arr){
newarry[i]=fn(arr[i]);
}
return newarry;
}
const sq = function(x){
return x*x;
}
console.log(map1(sq,[1,2,3,4]))
箭頭函數就是匿名函數,它是一種更加精簡的格式
箭頭函數參數
如果一個函數沒有參數,則使用()
如果只有一個參數,參數列表可以省略小括號
多個參數不能省略小括號,且使用逗號間隔
箭頭函數返回值
如果函數體部分有多行,就需要使用{},如果有返回值則使用return。
如果只有一行語句,可以同時省略大括號和return
只有一條return語句,不能省略大括號,有return必須有大括號
如果只有一條非return語句,加上大括號,函數無返回值
將上述實例中的函數修改為箭頭函數
const map1= (fn,arr) => {
newarry=[];
for (i in arr){
newarry[i]=fn(arr[i]);
}
return newarry;
}
const sq = (x) => x*x;
console.log(map1(sq,[1,2,3,4]))
結果如下
const map1= (fn,arr) => {
newarry=[];
for (i in arr){
newarry[i]=fn(arr[i]);
}
return newarry;
}
let new1 = map1((function (x) {return x*x}),[1,2,3,4]) //函數
let new2=map1((x)=> {return x*x},[1,2,3,4] ) //去除function ,將后面的變為(x) => {return x}形式
let new3 =map1((x)=> x*x,[1,2,3,4]) //若只有一個返回值,則可以省略{},但{} 和return是同時存在,因此可以寫成如下
let new4 =map1( x => x*x,[1,2,3,4]) //如果只有一個參數,則可以省略()
console.log(new1)
console.log(new2)
console.log(new3)
console.log(new4)
結果如下
const add = (x,y) => x+y;
console.log('add',add(4,5))
const add1 = (x,y=5) => x+y; //支持默認參數
console.log('add1',add1(4))
const add2 = (x=6,y) => x+y;
console.log('add2',add2(1)) //此處默認會將x=6代替為x=1,而y的值為undefined其傳入的值為add2(1,undefined)
console.log('add2',add2(1,10))
console.log('add2',add2(y=10,z=20)) //此處的結果為30,其不關心形式參數,此處為add2(10,20)
console.log('add2',add2(a=1000,b=3000,c=4000)) //多傳遞參數沒錯,只匹配前面的
結果如下
JS 基本參數總結
1 JS 中并沒有python中的關鍵字傳參
2 JS 只是再做參數位置的對應
3 JS 并不限制默認參數的位置
4 JS 多傳遞參數沒影響,其只是做位置的匹配操作
const add = (...args) => { // 可變參數 ,默認結果為列表
result=0;
console.log(args);
for (let x in args) {
result += args[x];
}
return result;
}
console.log(add(1,2,3,4,5))
和python 類似,JS提供了參數解構,依然使用了...符號來解構。
const add =(...args) => {
console.log(args)
}
add(1,2,3,4)
l1=[1,2,3,4]
add(l1)
//參數解構
console.log(...l1)
add(...l1)
結果如下
函數的所有參數都會被保存在一個arguments的鍵值對字典對象中。
(function (p1,...args) {
console.log(p1);
console.log(args);
console.log('---------------');
console.log(arguments,typeof(arguments));
for (let x of arguments)
console.log(x);
})('abcd',1,2,3,4,5) //此處是調用操作
結果如下
全局對象
console.log(arguments)
結果如下
在函數外,其指的是全局的,在函數內,其是函數中的參數
基本表達式和python差不多
function * inc(){ //使用* 來定義生成器
let i=0;
while (1)
yield (++i);
}
g=inc() //實例化生成器
console.log(g.next().value,g.next()) //執行生成器調用
console.log(g.next().value)
console.log(g.next().value)
console.log(g.next().value,g.next())
結果如下
每次調用next()方法返回一個對象,這個對象包含兩個屬性: value和done,value屬性表示本次yield表達式的返回值,done屬性為布爾值,done是false表示后續還有yield語句執行,如果執行完成或者return后,none為true。
function * inc(){
let i=0;
while (true) {
yield ++i;
if (i>3)
return i;
}
}
g= inc()
console.log(g.next())
console.log(g.next())
console.log(g.next())
console.log(g.next())
console.log(g.next())
結果如下
JS 使用大括號構成語句塊
ES6 之前語句塊是沒有作用域的,從ES6開始支持塊作用域,let只能在塊作用域中可見。
function??hello(){
????let?a=1;
????var?b=2;
????c=3
}
let?d=100
if?(1)
{
????let?d=4;?//局部和下一級有效,除非被覆蓋掉
????var?e=5
????f=6
????if?(true)?{
????????console.log(d)
????????console.log(e)
????????console.log(f)
????????console.log('____________________')
????????g=10??//只要不是函數,都沒問題
????????var?h=11??//只要是函數,都沒問題
????}
}
//console.log(a)??//不可見
//console.log(b)??//不可見
//console.log(c)??//不可見
console.log(d)??//不可見??let?突破不了塊作用域,但外界共享
console.log(e)?//var可見
console.log(f)??//隱式聲明,可見
console.log(g)?//可見
console.log(h)??//可見
結果如下
塊作用域只對let有效,對var和隱式聲明等特性無效
函數中var 和 let 都突破不了
塊作用域向下是穿透的,除非覆蓋問題
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。