前端之:js


JavaScript概述

ECMAScript和JavaScript的關系

  1996年11月,JavaScript的創造者--Netscape公司,決定將JavaScript提交給國際標准化組織ECMA,希望這門語言能夠成為國際標准。次年,ECMA發布262號標准文件(ECMA-262)的第一版,規定了瀏覽器腳本語言的標准,並將這種語言稱為ECMAScript,這個版本就是1.0版。

  該標准一開始就是針對JavaScript語言制定的,但是沒有稱其為JavaScript,有兩個方面的原因。一是商標,JavaScript本身已被Netscape注冊為商標。二是想體現這門語言的制定者是ECMA,而不是Netscape,這樣有利於保證這門語言的開發性和中立性。

  因此ECMAScript和JavaScript的關系是,前者是后者的規格,后者是前者的一種實現。

ECMAScript的歷史

年份 名稱 描述
1997 ECMAScript 1 第一個版本
1998 ECMAScript 2 版本變更
1999 ECMAScript 3

添加正則表達式

添加try/catch

  ECMAScript 4 沒有發布
2009 ECMAScript 5

添加"strict mode"嚴格模式

添加JSON支持

2011 ECMAScript 5.1 版本變更
2015 ECMAScript 6 添加類和模塊
2016 ECMAScript 7

增加指數運算符(**)

增加Array.prototype.includes

 

  注:ES6就是指ECMAScript 6。

  盡管 ECMAScript 是一個重要的標准,但它並不是 JavaScript 唯一的部分,當然,也不是唯一被標准化的部分。實際上,一個完整的 JavaScript 實現是由以下 3 個不同部分組成的:

  • 核心(ECMAScript) 
  • 文檔對象模型(DOM) Document object model (整合js,css,html)
  • 瀏覽器對象模型(BOM) Broswer object model(整合js和瀏覽器)

  簡單地說,ECMAScript 描述了JavaScript語言本身的相關內容。

  JavaScript 是腳本語言
  JavaScript 是一種輕量級的編程語言。后來出現了node.js,可以作為后端語言來開發項目,js是一個既能做前端又能做后端的語言,但是js這個作者用了10天就開發了這么個語言,所以寫的不是很完善,這個語言有很多的槽點,后面學習起來大家就知道啦。

  JavaScript 是可插入 HTML 頁面的編程代碼。

  JavaScript 插入 HTML 頁面后,可由所有的現代瀏覽器執行。

  JavaScript 很容易學習。

JavaScript引入方式

  1. Script標簽內寫代碼

在head標簽里面可以寫,在body標簽里面也可以寫,放到head標簽里面和放到body標簽里面到底有什么區別,我們后續在講~
<script> // 在這里寫你的JS代碼
 //console.log('騎士計划!') #f12建打開瀏覽器的調試窗口,然后在console這個調試台就能看到這個內容了
//alert('騎士計划!') #這個是瀏覽器窗口一打開咱們這個文件,就彈出一個窗口 </script>

    console:

    

    alert:

    

    

 

  2. 引入額外的JS文件

<script src="myscript.js"></script>

JavaScript語言規范

  注釋(注釋是代碼之母)

// 這是單行注釋

/*
這是
多行注釋 */

  結束符

  JavaScript中的語句要以分號(;)為結束符。也就是說和縮進沒關系了

 

JavaScript語言基礎

變量聲明

  1.JavaScript的變量名可以使用_,數字,字母,$組成,不能以數字開頭。

  2.聲明變量使用 var 變量名; 的格式來進行聲明

var name = "Alex";
也可以分兩步,聲明變量var name;然后name='Alex',但是通常我們都是一步寫完 var age = 18;

  注意:

  變量名是區分大小寫的。

  推薦使用駝峰式命名規則。首字母大寫

  保留字不能用做變量名。

  補充:(ES6新特性,等咱們學到 VUE 在細說,簡單了解一下就行了

  ES6新增了let命令,用於聲明變量。其用法類似於var,但是所聲明的變量只在let命令所在的代碼塊內有效。例如:for循環的計數器就很適合使用let命令。

for (let i=0;i<arr.length;i++){...}

  ES6新增const用來聲明常量。一旦聲明,其值就不能改變。這個東西就是為了定義一個固定的常量,供大家使用,這個常量不會改變

const PI = 3.1415;
PI // 3.1415

PI = 3
// TypeError: "PI" is read-only

  再次補充:保留字列表,不用硬記,寫多了自然就知道了

View Code

JavaScript數據類型

JavaScript擁有動態類型(python也是動態的)

var x;  // 此時x是undefined  靜態語言比如c:創建變量的時候,要指定變量的類型,python3.6也出現了類型注解的新特性def func(x:int,y:int) --> int: return x + y,意思是參數是int類型,返回值也是int類型的,就是個注釋的作用
var x = 1;  // 此時x是數字
var x = "Alex"  // 此時x是字符串 

數值(Number)

  JavaScript不區分整型和浮點型,就只有一種數字類型。

var a = 12.34;
var b = 20;
var c = 123e5;  // 12300000
var d = 123e-5;  // 0.00123

  還有一種NaN,表示不是一個數字(Not a Number),也就是說是一個值,但不是數字。

  常用方法:

parseInt("123")  // 返回123
parseInt("ABC")  // 返回NaN,NaN屬性是代表非數字值的特殊值。該屬性用於指示某個值不是數字。
parseFloat("123.456")  // 返回123.456

var a2 = 1.11
typeof(a2)
"number"

parseInt('123')
123

parseFloat('123.456')
123.456

a3 = parseFloat('123.123')
123.123

typeof(a3)
"number"

a4 = parseInt('123a')
123
typeof(a3)
"number"

a5 = parseInt('abc')
NaN

字符串(String)

var a = "Hello"
var b = "world;
var c = a + b; 
console.log(c);  // 得到Helloworld

  常用方法:

方法 說明
.length   #不加括號的是屬性 返回長度
.trim()    #得到一個新值 移除空白
.trimLeft() 移除左邊的空白
.trimRight() 移除右邊的空白
.charAt(n) #n類似索引,從0開始,超過最大值返回''空字符串 返回第n個字符
.concat(value, ...) #s1='hello';s.concat('xx');得到helloxx 拼接
.indexOf(substring, start) #這個start是從索引幾開始找,沒有返回-1 子序列位置
.substring(from, to) #不支持負數,所以一般都不用它,了解一下就行了 根據索引獲取子序列
.slice(start, end) #var s1='helloworld';s1.slice(0,-5)看結果,就用它 切片
.toLowerCase() #全部變小寫 小寫
.toUpperCase()  #全部變大寫 大寫
.split(delimiter, limit)#分隔,s1.splite(' '),后面還可以加參數s1.split(' ',2),返回切割后的元素個數 分割

 

常用方法示例

拼接字符串一般使用“+”

  slice和substring的區別:

string.slice(start, stop)和string.substring(start, stop):

兩者的相同點:
如果start等於end,返回空字符串
如果stop參數省略,則取到字符串末
如果某個參數超過string的長度,這個參數會被替換為string的長度

substirng()的特點:
如果 start > stop ,start和stop將被交換
如果參數是負數或者不是數字,將會被0替換

silce()的特點:
如果 start > stop 不會交換兩者
如果start小於0,則切割從字符串末尾往前數的第abs(start)個的字符開始(包括該位置的字符)
如果stop小於0,則切割在從字符串末尾往前數的第abs(stop)個字符結束(不包含該位置字符)


slice和substring的區別

  補充:

  ES6中引入了模板字符串。模板字符串(template string)是增強版的字符串,用反引號(`)標識,ESC鍵下面那個鍵就是反引號。它可以當做普通字符串使用,也可以用來定義多行字符串,或者在字符串中嵌入變量。你使用chorme瀏覽器就行,chorme瀏覽器支持ES6

// 普通字符串
`這是普通字符串!`
// 多行文本
`這是多行的
文本`
// 字符串中嵌入變量
var name = "q1mi", time = "today";
`Hello ${name}, how are you ${time}?`

    

 

  上面的寫法是ES6中的,並且在console中輸入內容的時候,按着shift+回車來進行換行,就能夠不執行代碼直接換行了~~~

  注意:

  如果模板字符串中需要使用反引號,則在其前面要用反斜杠轉義。

  JSHint啟用ES6語法支持:/* jshint esversion: 6 */

布爾值(Boolean)

  區別於Python,true和false都是小寫。

var a = true;
var b = false;

  ""(空字符串)、0、null、undefined、NaN都是false。

null和undefined

  • null表示值是空,一般在需要指定或清空一個變量時才會使用,如 name=null;
  • undefined表示當聲明一個變量但未初始化時,該變量的默認值是undefined。還有就是函數無明確的返回值時,返回的也是undefined。

    null表示變量的值是空,undefined則表示只聲明了變量,但還沒有賦值。

    還不明白,上圖吧!

對象(Object)

  JavaScript 中的所有事物都是對象:字符串、數值、數組、函數...此外,JavaScript 允許自定義對象。

  JavaScript 提供多個內建對象,比如 Number、String、Date、Array 等等,通過new實例化的對象都是object類型(var s = new String('hello'),var n = new Number(12)等),數組不需要new生命,類型就是object類型。

  對象只是帶有屬性和方法的特殊數據類型。

數組

  數組對象的作用是:使用單獨的變量名來存儲一系列的值。類似於Python中的列表。

var a = [123, "ABC"]; 
console.log(a[1]);  // 輸出"ABC"

       常用方法:

方法 說明
.length 數組的大小
.push(ele) 尾部追加元素
.pop() 獲取尾部的元素
.unshift(ele) 頭部插入元素
.shift() 頭部移除元素
.slice(start, end) 切片
.reverse() #在原數組上改的 反轉
.join(seq)#a1.join('+'),seq是連接符 將數組元素連接成字符串
.concat(val, ...) #連個數組合並,得到一個新數組,原數組不變 連接數組
.sort()   排序
.forEach() #講了函數再說 將數組的每個元素傳遞給回調函數
.splice() #參數:1.從哪刪(索引), 2.刪幾個  3.刪除位置替換的新元素(可多個元素) 刪除元素,並向數組添加新元素。
.map()  #講了函數再說 返回一個數組元素調用函數處理后的值的新數組

      

      concat示例:

      

常用方法示例

  關於sort()需要注意:

  如果調用該方法時沒有使用參數,將按字母順序對數組中的元素進行排序,說得更精確點,是按照字符編碼的順序進行排序。要實現這一點,首先應把數組的元素都轉換成字符串(如有必要),以便進行比較。

      

  上面的這種比較方式不是我們想要的啊,怎么辦?

  如果想按照其他標准進行排序,就需要提供比較函數,也就是自己提供一個函數提供排序規則,該函數要比較兩個值,然后返回一個用於說明這兩個值的相對順序的數字。比較函數應該具有兩個參數 a 和 b,其返回值如下:

    若 a 小於 b,在排序后的數組中 a 應該出現在 b 之前,則返回一個小於 0 的值。
    若 a 等於 b,則返回 0。
    若 a 大於 b,則返回一個大於 0 的值。

  示例:

function sortNumber(a,b){
    return a - b
}
var arr1 = [11, 100, 22, 55, 33, 44]
arr1.sort(sortNumber)

  對象數組排序:

對象數組排序示例

  關於遍歷數組中的元素,可以使用下面的兩種方式:

var a = [10, 20, 30, 40];
#方式一 for (var i=0;i<a.length;i++) { console.log(a[i]); }
#方式二
for (var i in a){
console.log(a[i])
}

forEach()(等學到后面再說這個)

  語法:

    forEach(function(currentValue, index, arr), thisValue)

  參數:

參數 描述
function(currentValue, index, arr) 必需。 數組中每個元素需要調用的函數。
函數參數:
參數 描述
currentValue 必需。當前元素
index 可選。當前元素的索引值。
arr 可選。當前元素所屬的數組對象。
thisValue 可選。傳遞給函數的值一般用 "this" 值。
如果這個參數為空, "undefined" 會傳遞給 "this" 值

splice()

  語法:

    splice(index,howmany,item1,.....,itemX)

  參數: 

參數 描述
index 必需。規定從何處添加/刪除元素。
該參數是開始插入和(或)刪除的數組元素的下標,必須是數字。
howmany 必需。規定應該刪除多少元素。必須是數字,但可以是 "0"。
如果未規定此參數,則刪除從 index 開始到原數組結尾的所有元素。
item1, ..., itemX 可選。要添加到數組的新元素

      看使用:

      

 

map()(后面再講)

  語法:

  map(function(currentValue,index,arr), thisValue)

  參數:

參數 描述
function(currentValue, index,arr) 必須。函數,數組中的每個元素都會執行這個函數
函數參數:
參數 描述
currentValue 必須。當前元素的值
index 可選。當期元素的索引值
arr 可選。當期元素屬於的數組對象
thisValue 可選。對象作為該執行回調時使用,傳遞給函數,用作 "this" 的值。
如果省略了 thisValue ,"this" 的值為 "undefined"

  補充:

  ES6新引入了一種新的原始數據類型(Symbol),表示獨一無二的值。它是JavaScript語言的第7種數據類型。

  

內置對象和方法

  JavaScript中的所有事物都是對象:字符串、數字、數組、日期,等等。在JavaScript中,對象是擁有屬性和方法的數據。

  我們在學習基本數據類型的時候已經帶大家了解了,JavaScript中的Number對象、String對象、Array對象等。

  注意var s1 = "abc"和var s2 = new String("abc")的區別:typeof s1 --> string而 typeof s2 --> Object

    

自定義對象

  JavaScript的對象(Object)本質上是鍵值對的集合(Hash結構),但是只能用字符串作為鍵。

var a = {'name': 'taibai','age': 18};
typeof a;
"object"
// 可以通過簡直對的形式取值
a['name'];
"taibai"
// 可以通過萬能的點取值
a.age
18

  遍歷對象中的內容:

var a = {"name": "Alex", "age": 18};
for (var i in a){
  console.log(i, a[i]);
}

事情並沒有那么簡單...

  

     

      

  

類型查詢

typeof "abc"  // "string"
typeof null  // "object"
typeof true  // "boolean"
typeof 123  typeof NAN // "number"
typeof undefined //undefined

  typeof是一個一元運算符(就像++,--,!,- 等一元運算符),不是一個函數,也不是一個語句。

  對變量或值調用 typeof 運算符將返回下列值之一:

  • undefined - 如果變量是 Undefined 類型的
  • boolean - 如果變量是 Boolean 類型的
  • number - 如果變量是 Number 類型的
  • string - 如果變量是 String 類型的
  • object - 如果變量是一種引用類型或 Null 類型的,需要注意的是typeof null返回為object,因為特殊值null被認為是一個空的對象引用。

      

運算符

算數運算符

+ - * / % ++ --  i++,是i自加1,i--是i自減1   i++的這個加1操作優先級低,先執行邏輯,然后再自加1,而++i,這個加1操作優先級高,先自加1,然后再執行代碼后面的邏輯

比較運算符

> >= < <= != == === !==

  注意:

1 == “1”  // true  #弱等於,將1轉換為字符串'1',在=號兩個數據類型不同的時候,會自動給你變成相同的,具體怎么一個變換規則,先不用理他,因為這種比較不好,因為以后咱們就盡量用===。
1 === "1"  // false #強等於,比較類型也比較值
var i = 10;
var b = '10'; // == 若等於,看着像是相等的 i == b; true // === 強等於,必須一樣 i === b; false i!=b; // 看着好像不相等的 false // 絕對是不等的 i!==b; true

提一個輸入法的高級用法:搜狗輸入法的一個高級用法:不認識的字:先輸入一個字母uhuohuohuo,就看到了焱,不會寫大寫的12345怎么辦?先輸入一個v12345,你就看到壹萬貳仟叄佰肆拾伍了。

邏輯運算符

&& || !  #and,or,非(取反)!null返回true
1 && 0; // 等同於and
0
1 || 0; // 等同於or
1
!0; // 等同於 not
true

賦值運算符

= += -= *= /=  #n += 1其實就是n = n + 1


好了同志們,學到這里就練習練習吧~~~然后在學~~~

 

流程控制

  if-else 

var a = 10;
if (a > 5){
  console.log("yes");
}else {
  console.log("no");
}

  if-else if-else  #多條件

var a = 10;
if (a > 5){
  console.log("a > 5");
}else if (a < 5) {
  console.log("a < 5");
}else {
  console.log("a = 5");
}

  switch 切換

var day = new Date().getDay(); //示例化一個今天的日期對象,getDay()是獲取天數的編號,0表示星期日
switch (day) {  //這里day這個參數必須是一個值或者是一個能夠得到一個值的算式才行,這個值和后面寫的case后面的值逐個比較,滿足其中一個就執行case對應的下面的語句,然后break,如果沒有加break,還會繼續往下判斷
  case 0: //如果day是0
  console.log("Sunday"); //執行它
  break; //然后break跳出
  case 1:
  console.log("Monday");
  break;
default:  //如果沒有任何滿足條件的,就執行它
  console.log("...")
}

滿足多個條件中的一個就執行對應邏輯的寫法:
switch(2){ case 1: case 2: case 3: console.log("c"); //當變量值為1,2,3中的任何一個時,都會在控制台打印出c break; default: console.log("d"); }


switch(2){ case 1: console.log(55); case 2:console.log(66); case 3: console.log("c"); //當變量值為1,2,3中的任何一個時,都會在控制台打印出c break; default: console.log("d"); }
打印結果:
66 c
如果滿足條件的沒有break;那么會按照上面滿足多個條件中的一個就執行對應邏輯的寫法:
並且會執行case條件滿足后的那個代碼。

var i = 5;
// 每個條件對應的結果后面必須加break,如果不加break,滿足條件的case執行完畢之后,下面的case無論條件滿足與否,都會執行。
switch (i) {
case 3:
console.log('數字3');
break;
case 4:
console.log('數字4');
break;
case 5:
console.log('數字5');
break;
case 6:
console.log('數字6');
break;
default:
console.log('沒有符合條件的結果')
};

// 多條件執行同一個結果的示例:
var i = 5;

switch (i) {
case 3: case 4: case 5:
console.log('多個條件執行同一個結果');
break;
default:
console.log('沒有符合條件的結果');
}

  switch中的case子句通常都會加break語句,否則程序會繼續執行后續case中的語句。

  for

for (var i=0;i<10;i++) {  //就這么個寫法,聲明一個變量,變量小於10,變量每次循環自增1,for(;;){console.log(i)};這種寫法就是個死循環,會一直循環,直到你的瀏覽器崩了,就不工作了,回頭可以拿別人的電腦試試~~
  console.log(i);
}

// 從1打印到10
// for (變量;限制條件;循環方式) {}
for (var i = 0;i < 11;++i){
console.log(i)
};

// 循環數組:將數組的索引與元素對應打印出來。
var l1 = ['a', 'b', 'c', 'd', 'e']
for (var i= 0;i<l1.length;i++){
console.log(i,l1[i]);
};

// 直接循環一個列表,得到的是每個元素的索引:
for (i in l1){
console.log(i,l1[i]);
};

// 循環字典時,循環體中不能使用點獲取值。
var dict1 = {'name':'太白','age':10}
for (var k in dict1){
console.log(k,dict1.k);
}// 獲取不到

var dict1 = {'name':'太白','age':10}
for (var k in dict1){
console.log(k,dict1[k]);
}// 這樣才可以

  while

var i = 0;
while (i < 10) {
  console.log(i);
  i++;
}

  三元運算

var a = 1;
var b = 2;
var c = a > b ? a : b //如果a>b這個條件成立,就把冒號前面的值給c,否則把冒號后面的值給c   //python中的:a = x if x>y else y

來吧,大家練習一下~~~~

  在我們的pycharm中可以更改js的版本

    

 

函數

函數定義

  JavaScript中的函數和Python中的非常類似,只是定義方式有點區別。

// 普通函數定義
function f1() {
  console.log("Hello world!");
}

// 帶參數的函數
function f2(a, b) {
  console.log(arguments);  // 內置的arguments對象
  console.log(arguments.length);
  console.log(a, b);
}

// 帶返回值的函數
function sum(a, b){
  return a + b;  //在js中,如果你想返回多個值是不行的,比如return a ,b;只能給你返回最后一個值,如果就想返回多個值,你可以用數組包裹起來 return [a,b];
}
sum(1, 2);  // 調用函數  sum(1,2,3,4,5)參數給多了,也不會報錯,還是執行前兩個參數的和,sum(1),少參數或者沒參數也不報錯,不過返回值就會是NAN

// 匿名函數方式,多和其他函數配合使用,后面我們就會用到了
var sum = function(a, b){  //在es6中,使用var,可能會飄黃,是因為在es6中,建議你使用let來定義變量,不過不影響你使用
  return a + b;  
}
sum(1, 2);

// 立即執行函數,頁面加載到這里,這個函數就直接執行了,不需要被調用執行
(function(a, b){
  return a + b;
})(1, 2);  //python中寫可以這么寫:ret=(lambda x,y:x+y)(10,20) 然后print(ret)

  補充:

    ES6中允許使用“箭頭”(=>)定義函數,可以理解為匿名函數,用的不多。

var f = v => v;
// 等同於
var f = function(v){
  return v;
}

    如果箭頭函數不需要參數或需要多個參數,就是用圓括號代表參數部分:

var f = () => 5;
// 等同於
var f = function(){return 5};

var sum = (num1, num2) => num1 + num2;
// 等同於
var sum = function(num1, num2){
  return num1 + num2;
}

函數中的arguments參數

function add(a,b){
  console.log(a+b);
  console.log(arguments.length) //獲取傳入的參數的個數,arguments就是指的你傳入的所有的實參,放在一個數組里面,這個arguments.length是統計這個數組的元素的個數。
}

add(1,2)

  輸出:

3
2

  注意:

    函數只能返回一個值,如果要返回多個值,只能將其放在數組或對象中返回。

函數的全局變量和局部變量

  局部變量

  在JavaScript函數內部聲明的變量(使用 var)是局部變量,所以只能在函數內部訪問它(該變量的作用域是函數內部)。只要函數運行完畢,本地變量就會被刪除。

  全局變量:

  在函數外聲明的變量是全局變量,網頁上的所有腳本和函數都能訪問它。

  變量生存周期:

    JavaScript變量的生命期從它們被聲明的時間開始。

    局部變量會在函數運行以后被刪除。

    全局變量會在頁面關閉后被刪除。

作用域

  首先在函數內部查找變量,找不到則到外層函數查找,逐步找到最外層。

  幾個例子:

    1.

var city = "BeiJing";
function f() {
  var city = "ShangHai";
  function inner(){
    var city = "ShenZhen";
    console.log(city);
  }
  inner();
}

f();  //輸出結果是? 

    2.

var city = "BeiJing";
function Bar() {
  console.log(city);
}
function f() {
  var city = "ShangHai";
  return Bar;
}
var ret = f();
ret();  // 打印結果是?

    3.閉包

var city = "BeiJing";
function f(){
    var city = "ShangHai";
    function inner(){
        console.log(city);
    }
    return inner;
}
var ret = f();
ret();   ---> ShangHai

詞法分析

(嘗試理解~~不理解也沒事兒~~不講~~)

  JavaScript中在調用函數的那一瞬間,會先進行詞法分析。

  詞法分析的過程:

    當函數調用的前一瞬間,會先形成一個激活對象:Avtive Object(AO),並會分析以下3個方面:

      1:函數參數,如果有,則將此參數賦值給AO,且值為undefined。如果沒有,則不做任何操作,但是一般有參數的時候,我們在執行函數的時候就把參數賦值給了這個參數,所以不會打印出undefined的效果。
      2:函數局部變量,如果AO上有同名的值,則不做任何操作。如果沒有,則將此變量賦值給AO,並且值為undefined。
      3:函數聲明,如果AO上有,則會將AO上的對象覆蓋。如果沒有,則不做任何操作。

    函數內部無論是使用參數還是使用局部變量都到AO上找。

    看兩個例子:

var age = 18;
function foo(){
  console.log(age);  //分析到這一步的時候,發現你下面有age變量聲明,那么age變量就在AO對象上存上了,並且值為undefined,所以函數在執行的時候,還沒有到age=22這步的時候,age=undefined
  var age = 22;      //如果沒有這個變量聲明,那么打印的結果應該是18
  console.log(age);
}
foo();  // 問:執行foo()之后的結果是?

undefined
22

     第二題:

var age = 18;
function foo(){
  console.log(age);
  var age = 22;
  console.log(age);
  function age(){   #發現age這個函數名也是變量,將OA上的變量給替換了,那么函數在執行的時候,去OA上找,發現OA是個函數,然后執行到age=22的時候,age才被重新賦值
    console.log("呵呵");
  }
  console.log(age);
}
foo();  // 執行后的結果是?

結果:

  function age(){
    console.log("呵呵");
  }
  22
  22

   答案解析:

詞法分析過程:
1、分析參數,有一個參數,形成一個 AO.age=undefine;
2、分析變量聲明,有一個 var age, 發現 AO 上面已經有一個 AO.age,因此不做任何處理
3、分析函數聲明,有一個 function age(){...} 聲明, 則把原有的 age 覆蓋成 AO.age=function(){...};

最終,AO上的屬性只有一個age,並且值為一個函數聲明

執行過程:
注意:執行過程中所有的值都是從AO對象上去尋找

1、執行第一個 console.log(age) 時,此時的 AO.age 是一個函數,所以第一個輸出的一個函數
2、這句 var age=22; 是對 AO.age 的屬性賦值, 此時AO.age=22 ,所以在第二個輸出的是 22
3、同理第三個輸出的還是22, 因為中間再沒有改變age值的語句了

這些內容就是好多人搞不明白的,經常寫js代碼的時候,發現自己的結果不對啊,什么情況,就是因為這個沒搞清楚~~~


答案解析

 

面向對象

  創建對象:

var person=new Object();  // 創建一個person對象
person.name="Alex";  // person對象的name屬性
person.age=18;  // person對象的age屬性

  面向對象,在ES5中沒有類的概念,只有個構造函數,命名的首字母要大寫,實例化的時候使用new關鍵字進行實例化

function Person(name){
    this.name=name
}

console.log(p1.name)  
Person.prototype.func1 = function(){ //添加一些方法,使用prototype,叫做原型鏈 方法
console.log(this.name,'愛編程!')
}
var p1 = new Person('chao');
p1.func1() #方法和屬性只能通過對象來調用,不能使用類名來調用
#chao
#chao 愛編程! 類似於python中的面向對象,了解一下就可以了

 

  注意:

  ES6中提供了Map數據結構。它類似於對象,也是鍵值對的集合,但是“鍵”的范圍不限於字符串,各種類型的值(包括對象)都可以當做鍵。

  也就是說,Object結構提供了“字符串--值”的對應,Map結構提供了“值--值”的對應,是一種更完善的Hash結構實現。

  map的使用:(map也是了解內容,有興趣的可以研究一下)

var m = new Map();
var o = {p: "Hello World"}

m.set(o, "content")
m.get(o) // "content"

m.has(o) // true
m.delete(o) // true
m.has(o) // false

   擴展:JavaScript面向對象之繼承:(目前作為了解,大家有興趣的可以自行研究一下)

// 父類構造函數
var Car = function (loc) {
this.loc = loc;
};

// 父類方法
Car.prototype.move = function () {
this.loc ++;
};

// 子類構造函數
var Van = function (loc) {
Car.call(this, loc);
};

// 繼承父類的方法
Van.prototype = Object.create(Car.prototype);
// 修復 constructor
Van.prototype.constructor = Van;
// 擴展方法
Van.prototype.grab = function () {
/* ... */
};

Date對象

  創建Date對象

//方法1:不指定參數
var d1 = new Date(); //獲取當前時間
console.log(d1.toLocaleString());  //當前時間日期的字符串表示
//方法2:參數為日期字符串
var d2 = new Date("2004/3/20 11:12");
console.log(d2.toLocaleString());
var d3 = new Date("04/03/20 11:12");  #月/日/年(可以寫成04/03/2020)
console.log(d3.toLocaleString());
//方法3:參數為毫秒數,了解一下就行
var d3 = new Date(5000);  
console.log(d3.toLocaleString());
console.log(d3.toUTCString());  
 
//方法4:參數為年月日小時分鍾秒毫秒
var d4 = new Date(2004,2,20,11,12,0,300);
console.log(d4.toLocaleString());  //毫秒並不直接顯示

  Date對象的方法:

var d = new Date(); 
//getDate()                 獲取日
//getDay ()                 獲取星期 ,數字表示(0-6),周日數字是0
//getMonth ()               獲取月(0-11,0表示1月,依次類推)
//getFullYear ()            獲取完整年份
//getHours ()               獲取小時
//getMinutes ()             獲取分鍾
//getSeconds ()             獲取秒
//getMilliseconds ()        獲取毫秒
//getTime ()                返回累計毫秒數(從1970/1/1午夜),時間戳
var d1 = new Date();
d1
Tue Oct 22 2019 17:45:37 GMT+0800 (中國標准時間) d1.toDateString(); "Tue Oct 22 2019" d1.toLocaleString(); "2019/10/22 下午5:45:37" var d2 = new Date('04/03/1988 11:12'); d2.toLocaleString(); "1988/4/3 上午11:12:00" var d = new Date(); d.getDate(); 22 d.getDay(); 2 d.getHours(); 17

練習:

  編寫js代碼,將當前日期按“2017-12-27 11:11 星期三”格式輸出。

  詳細Date對象方法:點我

JSON對象

var str1 = '{"name": "chao", "age": 18}';
var obj1 = {"name": "chao", "age": 18};
// JSON字符串轉換成對象
var obj = JSON.parse(str1); 
// 對象轉換成JSON字符串
var str = JSON.stringify(obj1);

RegExp對象

  RegExp相關:用的比較多 

//RegExp對象

//創建正則對象方式1
// 參數1 正則表達式(不能有空格)
// 參數2 匹配模式:常用g(全局匹配;找到所有匹配,而不是在第一個匹配后停止)和i(忽略大小寫)

// 用戶名只能是英文字母、數字和_,並且首字母必須是英文字母。長度最短不能少於6位 最長不能超過12位。

// 創建RegExp對象方式(逗號后面不要加空格),假如匹配用戶名是只能字母開頭后面是字母加數字加下划線的5到11位的
var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9_]{5,11}$"); //注意,寫規則的時候,里面千萬不能有空格,不然匹配不出來你想要的內容,除非你想要的內容本身就想要空格,比如最后這個{5,11},里面不能有空格

// 匹配響應的字符串
var s1 = "bc123";

//RegExp對象的test方法,測試一個字符串是否符合對應的正則規則,返回值是true或false。
reg1.test(s1); // true

// 創建方式2,簡寫的方式
// /填寫正則表達式/匹配模式(逗號后面不要加空格)
var reg2 = /^[a-zA-Z][a-zA-Z0-9_]{5,11}$/;

reg2.test(s1); // true

注意,此處有坑:如果你直接寫一個reg2.test(),test里面啥也不傳,直接執行,會返回一個true,用其他的正則規則,可能會返回false,是因為,test里面什么也不傳,默認傳的是一個undefined,並且給你變成字符串undefined,所以能夠匹配undefined的規則,就能返回true,不然返回false


// String對象與正則結合的4個方法
var s2 = "hello world";

s2.match(/o/g); // ["o", "o"] 查找字符串中 符合正則 的內容 ,/o/g后面這個g的意思是匹配所有的o,
s2.search(/h/g); // 0 查找字符串中符合正則表達式的內容位置,返回第一個配到的元素的索引位置,加不加g效果相同
s2.split(/o/g); // ["hell", " w", "rld"] 按照正則表達式對字符串進行切割,得到一個新值,原數據不變
s2.replace(/o/g, "s"); // "hells wsrld" 對字符串按照正則進行替換

// 關於匹配模式:g和i的簡單示例
var s1 = "name:Alex age:18";

s1.replace(/a/, "哈哈哈"); // "n哈哈哈me:Alex age:18"
s1.replace(/a/g, "哈哈哈"); // "n哈哈哈me:Alex 哈哈哈ge:18" 全局匹配
s1.replace(/a/gi, "哈哈哈"); // "n哈哈哈me:哈哈哈lex 哈哈哈ge:18" 不區分大小寫


// 注意事項1:
// 如果regExpObject帶有全局標志g,test()函數不是從字符串的開頭開始查找,而是從屬性regExpObject.lastIndex所指定的索引處開始查找。
// 該屬性值默認為0,所以第一次仍然是從字符串的開頭查找。
// 當找到一個匹配時,test()函數會將regExpObject.lastIndex的值改為字符串中本次匹配內容的最后一個字符的下一個索引位置。
// 當再次執行test()函數時,將會從該索引位置處開始查找,從而找到下一個匹配。
// 因此,當我們使用test()函數執行了一次匹配之后,如果想要重新使用test()函數從頭開始查找,則需要手動將regExpObject.lastIndex的值重置為 0。
// 如果test()函數再也找不到可以匹配的文本時,該函數會自動把regExpObject.lastIndex屬性重置為 0。

var reg3 = /foo/g;
// 此時 regex.lastIndex=0
reg3.test('foo'); // 返回true
// 此時 regex.lastIndex=3
reg3.test('xxxfoo'); // 還是返回true
// 所以我們在使用test()方法校驗一個字符串是否完全匹配時,一定要加上^和$符號,把匹配規則寫的確定一些,盡量不用上面這種的寫法/xxx/。

// 注意事項2(說出來你可能不信系列):
// 當我們不加參數調用RegExpObj.test()方法時, 相當於執行RegExpObj.test(undefined),然后將這個undefined又轉為字符串"undefined",去進行匹配了, 並且/undefined/.test()默認返回true。
var reg4 = /^undefined$/;
reg4.test(); // 返回true
reg4.test(undefined); // 返回true
reg4.test("undefined"); // 返回true


RegExp相關

坑:

var s = 'hello world';

s.match(/o/)
["o", index: 4, input: "hello world", groups: undefined]
s.match(/o/g)
(2) ["o", "o"]

s.search(/e/)
1
s.search(/e/g) // 只能找到1個
1

s.replace(/o/,'r')
"hellr world"

s.replace(/o/g,'r')
"hellr wrrld"

var s = 'Taibai tnb'
s.replace(/t/g,'666')
"Taibai 666nb"

s.replace(/t/i,'666') // 不區分大小寫,但是只能替換一個
"666aibai tnb"

var reg = /a/g;
var s = 'barry alen'

/* test 每次找到目標字符串之后,記錄索引位置,在進行test則從上次的位置繼續往下尋找
如果找到底查詢完畢了,會循環查詢*/
reg.test(s);
true
reg.test(s);
true
reg.test(s);
false
reg.test(s);
true
reg.lastIndex;  // 獲取目標索引下一個位置
2
reg.lastIndex = 0;  // 可以調整查詢索引位置
0
reg.test(s);
true

擴展閱讀

Math對象(類似於python的內置函數)

  Math:不需要new來創建對象,直接使用Math.下面的方法

Math.abs(x) 返回數的絕對值。
exp(x) 返回 e 的指數。
floor(x) 小數部分進行直接舍去。
log(x) 返回數的自然對數(底為e)。
max(x,y) 返回 x 和 y 中的最高值。
min(x,y) 返回 x 和 y 中的最低值。
pow(x,y) 返回 x 的 y 次冪。
random() 返回 0 ~ 1 之間的隨機數。
round(x) 把數四舍五入為最接近的整數。
sin(x) 返回數的正弦。
sqrt(x) 返回數的平方根。
tan(x) 返回角的正切。

    

 
         

var x = -10
Math.abs(x)
10
var x = 2
Math.exp(x)
7.38905609893065

 
         

var x = 3.1415
Math.floor(x)
3

 
         

var x = 5
Math.log(x)
1.6094379124341003

 
         

var x = 1;
var y = 3;
Math.max(x,y);
3
Math.min(x,y);
1
Math.pow(2,5);
32
Math.random()
0.46414671149111175
Math.random()
0.7975478310719861

 
         

Math.round(3.45)
3
Math.round(3.55)
4

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM