22javascript筆記(2)

  • 2021 年 8 月 18 日
  • 筆記

JavaScript

1.js事件和作用域

js事件:html頁面中每一個元素都可以產生某些觸發js函數的事件。這些事件是可以被js偵測到的一種行為,並且js程式能應對這些事件。

常見的html事件

onchange:html元素改變

onclick:用戶點擊html元素

onmouseover:用戶吧滑鼠移到html元素上

onmouseout:用戶從html元素移開滑鼠

onkeydown:用戶按下鍵盤按鍵

onkeyup:瀏覽器完成頁面的載入

HTML頁面完成載入

HTML輸入欄位被用戶更改

HTML按鈕被用戶點擊

 

設置元素的js事件:行內方法

<element event="JavaScript 程式碼"></element>
<element event='JavaScript 程式碼'></element>
<button onclick="getElementById('demo').innerHTML=Date()">

 

innerHTML屬性設置元素的內容

設置元素的事件:內部方法

 <button onclick="displayDate()">點擊這裡 p 標籤的內容將被修改</button>
<script>
      function displayDate() {
        document.getElementById("demo").innerHTML = Date();
      }
</script>

 

js作用域

js中有全局作用域和局部作用域

局部作用域:在函數內聲明的變數為局部變數,作用域只在函數內部有效,也只能被函數內部訪問。 不同函數中可以聲明同名的局部變數,局部變數的生命周期是函數的生命周期。

<script>
      myFtn();
    
      function myFtn() {
        var lanqiaoxueyuan = "www.lanqiao.cn";
       document.getElementById("demo1").innerHTML =
          "lanqiaoxueyuan" + " = " + lanqiaoxueyuan;
      }
      document.getElementById("demo2").innerHTML = typeof lanqiaoxueyuan;//undefined
</script>

 

全局作用域:在函數外聲明的變數。全局變數作用域針對整個全局。網頁的所有腳本和函數都能訪問它。

<script>
      var lanqiaoxueyuan = "www.lanqiao.cn";
      myFtn();
​
      function myFtn() {
        document.getElementById("demo").innerHTML =
          "我能顯示 " + lanqiaoxueyuan;
      }
</script>

 

自動全局:如果變數在函數內沒有聲明(沒有使用var關鍵字),該變數為全局變數。

<script>
      myFtn();
​
      // 此處的程式碼可以把 lanqiaoxueyuan 作為全局變數使用。
      document.getElementById("demo").innerHTML =
        "我可以顯示 " + lanqiaoxueyuan;//沒有聲明直接使用
function myFtn() {
        lanqiaoxueyuan = "www.lanqiao.cn";
      }
</script>

 

js變數生命周期

js變數在聲明時開始初始化,局部變數在函數銷毀後自動銷毀,全局變數在頁面關閉後進行銷毀

函數參數:只在函數內部起作用,是局部變數

全局變數:window是全局對象,因此任何全局變數都屬於window對象,是它的一個屬性。

如果沒有特殊需求,不要創建全局變數,因為它會覆蓋window變數(或函數),任何函數,包括window對象,能覆蓋全局變數和函數。

2.js字元串和運算符

js字元串:單引號或者雙引號引起來的unicode字元序列。用於存儲和操作文本。

str.length

轉移符號

通常,js字元串是原始數據,可以使用字元創建。

var lanqiaoxueyuan = "www.lanqiao.cn";

 

但也可以使用new關鍵字將字元串定義為一個對象。

var lanqiaoxueyuan = new String("www.lanqiao.cn");

 

雖然String對象可以創建,但是它會拖慢執行速度,並可能產生其他副作用。

因為字元串與對象、對象與對象無法比較。

js運算符:算術運算符 + – * / % ++(左、右) –(左、右)

賦值運算符: = += -= *= /= %=

字元串+數字、字元串+字元串

3.js的數據類型轉換

js六種可包含值的數據類型:

  • 字元串String

  • 數字Number

  • 布爾Boolean

  • 對象Object

  • 函數function

  • 唯一的symbol

三中對象類型:

  • 對象Object

  • 日期Date

  • 數組Array

兩種值唯一的數據類型:

  • null

  • undefined

使用typeof運算符返回變數、對象、表達式的類型

NaN的數據類型是Number

數組Array的數據類型是Object

日期Date的數據類型是Object

null的數據類型是Object

undefined的數據類型是undefined

undefined是null的一種,undefined == null為true

 

constructor屬性用於返回js變數的構造函數

<script>
      document.getElementById("demo").innerHTML =
        "JACK".constructor +//String()
        "<br>" +
        (3.14).constructor +//Number()
        "<br>" +
        false.constructor +//Boolean()
        "<br>" +
        [1, 2, 3, 4, 5].constructor +//Array()
        "<br>" +
        { name: "JACK", age: 36 }.constructor +//Object()
        "<br>" +
        new Date().constructor +//Date()
        "<br>" +
        function () {}.constructor;//Function()
    </script>

 

可以通過constructor屬性來確定某個對象是否為數組或日期(如果用typeof,都是object)

 <script>
      var haha = ["Women", "Meitian", "Douyao", "Kaixin"];
      document.getElementById("demo").innerHTML = isArray(haha);
      function isArray(myArray) {
        return myArray.constructor.toString().indexOf("Array") > -1;
      }
    </script>

 

js類型轉換

js類型轉換有兩種方式:使用js函數、js自身自動轉換

數字轉字元串:全局String()方法、number.toString()

布爾值轉字元串:全局String()方法、boolean.toString()

日期轉字元串:Date()返回字元串、String()

 

字元串轉數字:

全局Number():

字元串為數值,可以轉換成數字、空字元串轉換為0、其他字元串轉換為NaN(非數值類型)

Number("3.14"); // 返回 3.14
Number(" "); // 返回 0
Number(""); // 返回 0
Number("99 88"); // 返回 NaN

 

一元運算符+:

        var a = "6";//String
        var b = +a;//Number
        document.getElementById("demo").innerHTML =
          typeof a + "<br>" + typeof b;

 

使用+可以String轉換為Number,如果轉換不成功會變成NaN

布爾值轉數字:false為0 true為1

全局Number()方法

日期轉數字:轉換為毫秒數

全局Number()方法,等同於d.getTime()

 

自動類型轉換:

console.log(5 + null);//5 null轉為0
console.log("5" + null);//5null null轉為「null」
console.log("5" + 1);//51 1轉為「1」
console.log("5" - 1);//4 「5」轉為5

 

自動轉為字元串:

當嘗試輸出一個對象或變數時,會自動調用變數的toString()方法

 

布爾值與字元串:「」 「 」為false 有值的字元串為true

NaN為false +-Infinity為true

「」為數字0

[]為數字0,「」,true

[20]為數字20,”20″,true

function(){}為NaN,true

null為數字0,false

undefined為NaN,false

4.js的正則表達式

js的regex語法:/pattern/modifiers

var patt = /lanqiaoxueyuan/i;

 

js的正則表達式經常使用兩個字元串方法:

search():返回匹配的位置

replace():返回模式被替換出修改後的字元串

test():解析字元串,如果符合正則表達式返回true,否則返回false

 var str = "Search lanqiaoxueyuan";
 var a = str.search(/lanqiaoxueyuan/i);//7
 var str = document.getElementById("demo").innerHTML;
        var txt = str.replace(/lanqiaoxueyuan/i, "www.lanqiao.cn");
var a = new RegExp("f");
a.test(
          "Attitude determines life, and should not let life determine your attitude!"
        );
var patt1 = new RegExp("f");
 patt1.exec(
          "Attitude determines life, and should not let life determine your attitude!"
        );

 

regex修飾符:

i 執行對大小寫不敏感的匹配

g 執行全局匹配

m 執行多行匹配

regex常用模式:

(x|y):以|分割的選項

\d:數字

\w:數字、字母、下劃線

\b:單詞邊界

\uxxxx:Unicode(16進位)

\s:空白字元

量詞:

n+ 至少一個n

n* 任意n

n? 零個或一個n

5.原型

js中給函數提供了一個對象類型的屬性,叫做Prototype(原型)

原型歸所有函數所有,他不用創建 是默認存在存在的

function Car(){
​
}
var c1 = new Car();
var c2 = new Car();
Car.prototype.name = "BMW";
console.log(c1.name);
console.log(c2.name);

 

js提供了這樣的一種機制,如果是通過構造函數創建對象,當訪問你的屬性在對象中沒有找到,則去創建對象的構造函數中找,如果能找到,也相當於對象擁有這個屬性

原型的作用就是為類(函數)提供了一個公共區域,在這個公共區域聲明的屬性和方法能夠被所有通過這個類創建的對象所訪問到。

function Car(name,speed,ability){
     this.name = name;
     this.speed = speed;
     this.ability = ability;
 }
 Car.prototype.showAbility= function(){
     console.log(this.ability);
 }
 var c1 = new Car("BMW",240,"坐寶馬");
 var c2 = new Car("BZ",300,"開Benz");
 c1.showAbility();
 c2.showAbility();

 

原型是js為所有函數所創建的一個對象類型的屬性,原型當中的屬性和方法被所有的通過這個函數所創建的所有對象共享。

 

結構: 原型是一個對象,在原型中通常擁有兩個屬性

1 構造器: constructor 該屬性指向這個函數本身

2 原型指向

__proto__該屬性指向原型本身,提供給通過類創建的對象使用

作用: 原型用來創建類的共有屬性和共有方法,為創建對象服務

優點: 節約記憶體空間,不必為每一個對象分配共有屬性和共有方法的記憶體

缺點: 原型中不能保存數組這類引用類型的數據,因為地址的傳遞的問題 會導致出現修改的連鎖變換。

 

6.原型鏈

構造函數的屬性prototype可以設置共有屬性和共有方法 對象擁有proto和constructor屬性,但是函數也是一種對象,所以函數也有這兩種屬性 proto是由一個對象指向一個對象,即指向他們的原型對象(父對象)。proto 的作用是,當對象找一個屬性沒找到時,就去它的父對象里找,再往父對象的父對象里找。最後形成了一條原型鏈。 prototype是函數獨有的,從一個函數指向一個對象,也就是這個函數創建的實例的原型對象,即f1.proto===Foo().prototype。prototype屬性的作用是包含可以讓特定類型的所有實例共享的屬性和方法。 constructor是對象獨有的,從一個對象指向一個函數,含義就是指向該對象的構造函數。每個對象都有構造函數,Function的構造函數就是它自己。所以constructor的重點就是Function這個函數。

  
    console.log(c1.__proto__);//獲取到c1的構造函數的原型
        console.log(c1.__proto__===Car.prototype);//Car.prototype,true
        console.log(c1.__proto__.__proto__);//獲取到對象的原型,所有對象的原型即Object()定義的公共屬性和方法
        console.log(c1.__proto__.__proto__===Object.prototype);//Object.prototype,true
        console.log(c1.__proto__.__proto__.__proto__);//Object.prototype沒有公共屬性
        console.log(c1.__proto__.__proto__.__proto__);
        console.log(new Object().__proto__);//object對象.__proto__===Object()的原型
        console.log(new Object().constructor.prototype);//Object()的原型
        console.log(new Object().__proto__.__proto__);
        console.log(Object.prototype.constructor.prototype);//如果一直對Object對象調用構造方法再獲取公共屬性,會一直套娃。