Python 测开27期 - 柒柒 - JavaScript笔记

JS基础

JavaScript 用法

  • HTML 中的脚本必须位于 <script></script> 标签之间

  • 脚本可被放置在 HTML 页面的 <body><head> 部分中

  • 如需使用外部文件,在 <script> 标签的 “src” 属性中设置

    <!DOCTYPE html>
    <html>
    <body>
        <script src="myScript.js"></script>
    </body>
    </html>
    

JavaScript 输出

  • 使用 window.alert() 弹出警告框

  • 使用 document.write() 方法将内容写到 HTML 文档中
    如果在文档已完成加载后执行 document.write,整个 HTML 页面将被覆盖

  • 使用 innerHTML 写入到 HTML 元素
    document.getElementById("demo").innerHTML = "段落已修改"

  • 使用 console.log() 写入到浏览器的控制台


JavaScript 变量

var

  • 使用var关键字声明变量

    // 声明变量时未赋值,变量的值将是 undefined
    var name;
    // 声明多个变量
    var name,age,sex;
    // 声明变量赋值后,若重新声明JS变量,该变量的值不会丢失
    var name = 'wjq';
    var name;
    

JavaScript 数据类型

  • 值类型(基本类型)
    • 字符串(String)
    • 数字(Number)
    • 布尔(Boolean):true 或 false
    • 空(Null)
    • 未定义(Undefined)
    • Symbol :表示独一无二的值
  • 对象类型
    • 函数(Function)

    • 对象(Object):对象的属性以键值对的形式来定义

      // 创建对象
      var person={firstname:"John", lastname:"Doe", id:5566};
      // 获取对象的值
      name = person.lastname;
      name = person["lastname"];
      
    • 数组(Array)

      // 创建数组1
      var cars = new Array();
      // 创建数组2
      var cars = new Array("Saab","Volvo","BMW");
      // 创建数组3
      var cars=["Saab","Volvo","BMW"];
      

声明变量类型

// 使用new声明变量类型
var name=    new String;
var x=       new Number;
var y=       new Boolean;
var cars=    new Array;
var person=  new Object;

typeof 检查变量数据类型

  • 语法
    typeof 变量名
  • 实例
typeof "John"                // 返回 string
typeof 3.14                  // 返回 number
typeof NaN                    // 返回 number
typeof false                 // 返回 boolean
typeof [1,2,3,4]             // 返回 object
typeof {name:'John', age:34} // 返回 object
typeof new Date()             // 返回 object
typeof function () {}         // 返回 function
typeof null 									// 返回 object
typeof undefined							// 返回 undefined

constructor 属性

  • constructor 属性返回所有 JavaScript 变量的构造函数
  • 实例
"John".constructor                 // 返回函数 String()  { [native code] }
(3.14).constructor                 // 返回函数 Number()  { [native code] }
false.constructor                  // 返回函数 Boolean() { [native code] }
[1,2,3,4].constructor              // 返回函数 Array()   { [native code] }
{name:'John', age:34}.constructor  // 返回函数 Object()  { [native code] }
new Date().constructor             // 返回函数 Date()    { [native code] }
function () {}.constructor         // 返回函数 Function(){ [native code] }

JavaScript 类型转换

转换为字符串 (数字、布尔值、日期)

  • String(xx)
  • x.toString()

转换为数字 (字符串、布尔值、日期)

  • Number()
    • 字符串包含数字(如 “3.14”) 转换为数字 (如 3.14)
    • 空字符串转换为 0
    • 其他的字符串会转换为 NaN (不是个数字)
    • 可将布尔值转换为数字,true为1,false为0

JavaScript 函数

语法

function functionname(arg1,arg2)
{
    // 执行代码
	return xxx
}

JavaScript 作用域

局部变量

  • 变量在函数内声明,只能在函数内部访问
// 此处不能调用 carName 变量
function myFunction() {
    var carName = "Volvo";
    // 函数内可调用 carName 变量
}

全局变量

  • 变量在函数外定义

    var carName = " Volvo";
    // 此处可调用 carName 变量
    function myFunction() {
    	// 函数内可调用 carName 变量
    }
    
  • 如果变量在函数内没有声明(没有使用 var 关键字)

    // 此处可调用 carName 变量
    function myFunction() {
    	carName = "Volvo";
    	// 此处可调用 carName 变量
    }
    

HTML 中的全局变量

  • 在 HTML 中, 全局变量是 window 对象,所以window 对象可以调用函数内的局部变量
    //此处可使用 window.carName
    function myFunction() {
    	carName = "Volvo";
    }
    

JavaScript 事件

  • 当在 HTML 页面中使用 JavaScript 时, JavaScript 可以触发这些事件
  • 实例:
    <button onclick="getElementById('demo').innerHTML=Date()">现在的时间是?</button>
    

常见的HTML事件

  • onclick:用户点击 HTML 元素
  • onchange:HTML 元素改变
  • onmouseover:鼠标指针移动到指定的元素上时发生
  • onmouseout:用户从一个 HTML 元素上移开鼠标时发生
  • onkeydown:用户按下键盘按键
  • onload:浏览器已完成页面的加载

JavaScript 字符串

字符串长度

  • 使用内置属性 length 来计算字符串的长度 txt.length

模版字符串

  • 模版中可使用变量和表达式

    <script>
    const name = 'Runoob';
    const age = 30;
    const message = `My name is ${name} and I'm ${age} years old.`;
    document.getElementById("demo").innerHTML = message;
    </script>
    
  • 当html模版使用

    let header = "";
    let tags = ["RUNOOB", "GOOGLE", "TAOBAO"];
    let html = `<h2>${header}</h2><ul>`;
    for (const x of tags) {
      html += `<li>${x}</li>`;
    }
    html += `</ul>`;
    

JavaScript 运算符

算术运算符

  • x=++y 先计算,后赋值
  • x=y++ 先赋值,后计算

逻辑运算符

  • and:&&
  • or:||
  • not:!

条件运算

  • 语法 variablename=(condition)?value1:value2

JavaScript 条件语句

if 语句

  • 语法
    if (condition1)
    {
    	当条件 1 为 true 时执行的代码
    }
    else if (condition2)
    {
    	当条件 2 为 true 时执行的代码
    }
    else
    {
      当条件 1 和 条件 2 都不为 true 时执行的代码
    }
    

switch语句

  • 语法
    • 表达式 n(通常是一个变量)
    • 表达式的值会与结构中的每个 case 的值做比较,若匹配则执行,并使用break跳出switch
    • default 关键词来规定匹配不存在时做的事情
    switch(n)
    {
    	case 1:
    		执行代码块 1
    		break;
    	case 2:
    		执行代码块 2
    		break;
    	default:
    		与 case 1 和 case 2 不同时执行的代码
    }
    

JavaScript 循环语句

for 循环

  • 语法
    • 语句 1 (代码块)开始前执行
    • 语句 2 定义运行循环(代码块)的条件
    • 语句 3 在循环(代码块)已被执行之后执行
    for (var i=0; i<5; i++)
    {
    	  x=x + "该数字为 " + i + "<br>";
    }
    

for/in 循环

  • 循环获取对象属性、循环获取列表索引
  • 语法
    # 循环遍历对象的属性
    var person={fname:"Bill",lname:"Gates",age:56}; 
    for (x in person)  // x 为属性名
    {
    	txt=txt + person[x];
    }
    

while 循环

  • 语法
while (条件)
{
    需要执行的代码
}

do/while循环

  • do/while 循环会在检查条件是否为真之前执行一次代码块,然后如果条件为真的话,就会重复这个循环
  • 语法
do
{
    需要执行的代码
}
while (条件);

JavaScript 正则表达式

  • 语法 /正则表达式主体/修饰符(可选)
    • /runoob/i 是一个正则表达式
    • runoob 是一个正则表达式主体 (用于检索)
    • i 是一个修饰符 (搜索不区分大小写)

使用字符串方法

  • search() :返回子串的起始位置
  • replace(表达式,替换对象)

使用 RegExp 对象

  • test():检测一个字符串是否匹配某个模式,匹配返回 true,否则返回 false
var patt = /e/;
var patt1 = new RegExp("e");
patt.test("The best things in life are free!");
  • exec():用于检索字符串中的正则表达式的匹配

JavaScript 声明提升

  • 函数及变量的声明都将被提升到函数的最顶部
  • 只有声明的变量会提升,初始化的不会

JavaScript this 关键字

  • 在方法中,this 表示该方法所属的对象
  • 如果单独使用,this 表示全局对象
  • 在函数中,this 表示全局对象
  • 在函数中,在严格模式下,this 是未定义的(undefined)
  • 在事件中,this 表示接收事件的元素
  • 类似 call() 和 apply() 方法可以将 this 引用到任何对象

JavaScript let 和 const

let

  • let 声明的变量只在 let 命令所在的代码块内有效

let 和 var 的区别

  1. HTML 代码中使用全局变量
    • 使用 var 关键字声明的全局作用域变量属于 window 对象,用 window.xxx 访问变量
    • 使用 let 关键字声明的全局作用域变量不属于 window 对象,无法通过window访问
  2. 重置变量
    • 在相同的作用域或块级作用域中,不能使用 let 关键字来重置 var 和 let 声明的变量,也不能使用 var 关键字来重置 let 声明的变量
    • 同一个作用域内,let 声明的变量无法再次声明
  3. 变量提升
    • var 关键字定义的变量可以在使用后声明,也就是变量可以先使用再声明
    • let 关键字定义的变量则不可以在使用后声明,也就是变量需要先声明再使用

const

  • const 用于声明一个或多个常量,声明时必须进行初始化,且初始化后值不可再修改

const 和 let 的区别

  1. const声明的常量必须初始化,而let声明的变量不用
  2. const 定义常量的值不能通过再赋值修改,也不能再次声明。而 let 定义的变量值可以修改
  3. const 关键字无法重置 let 、 var 、const 声明的变量

JSON

  • JSON.parse() 用于将一个 JSON 字符串转换为 JavaScript 对象
  • JSON.stringify() 用于将 JavaScript 值转换为 JSON 字符串

JavaScript 函数定义

函数声明

function myFunction(a, b) {
    return a * b;
}
  • arguments.length 属性返回函数调用过程接收到的参数个数
  • toString() 方法将函数作为一个字符串返回 myFunction.toString()

箭头函数

  • 语法
(参数1, 参数2, …, 参数N) => 表达式(单一)
// 相当于:(参数1, 参数2, …, 参数N) =>{ return 表达式; }

// 当只有一个参数时,圆括号是可选的
(单一参数) => {函数声明}
单一参数 => {函数声明}

// 没有参数的函数应该写成一对圆括号
() => {函数声明}

// 实例
const x = (x, y) => { return x * y };

默认参数

  • 如果函数在调用时未提供隐式参数,参数会默认设置为: undefined,建议最好为参数设置一个默认值
// ES5需要为参数设置默认值 
function myFunction(x, y) {
    y = y || 0;
}

// ES6支持函数带有默认参数
function myFunction(x, y = 10) {
    return x + y;
}

arguments 对象

  • arguments 对象包含了函数调用的参数数组
// 创建一个函数用来统计所有数值的和
x = sumAll(1, 123, 500, 115, 44, 88);
// 使用arguments调用参数数组,无需在函数创建时,设置参数
function sumAll() {
    var i, sum = 0;
    for (i = 0; i < arguments.length; i++) {
        sum += arguments[i];
    }
    return sum;
}

JavaScript 函数调用

作为一个函数调用

// 全局对象返回 this 的值是 window 对象
function myFunction(a, b) {
    return a * b;
}
window.myFunction(10, 2);  //返回 20

函数作为方法调用

// 实例中 this 的值为 myObject 对象
var myObject = {
    firstName:"John",
    lastName: "Doe",
    fullName: function () {
        return this.firstName + " " + this.lastName;
    }
}
myObject.fullName();         // 返回 "John Doe"

使用构造函数调用函数

  • 构造函数中 this 关键字没有任何的值, this 的值在函数调用实例化对象时创建
// 构造函数:
function myFunction(arg1, arg2) {
    this.firstName = arg1;
    this.lastName  = arg2;
}
 
// This creates a new object
var x = new myFunction("John","Doe");
x.firstName;                             // 返回 "John"

作为函数方法调用函数

// call 依次传入参数值
function myFunction(a, b) {
    return a * b;
}
myObject = myFunction.call(myObject, 10, 2); 

// apply传入的是一个参数数组
function myFunction(a, b) {
    return a * b;
}
myArray = [10, 2];
myObject = myFunction.apply(myObject, myArray);  // 返回 20

JavaScript 类(class)

类声明

  • 类是用于创建对象的模板
  • constructor() 是类的构造函数,用于创建和初始化一个 class的对象
// 与python的init相似
class Runoob {
	constructor(name, url) {
	this.name = name;
	this.url = url;
	}
	fun1(){
		return this.name
	}
}

// 使用 new 关键字创建类对象
let site = new Runoob("菜鸟教程",  "https://www.runoob.com");

类继承

  • 使用 extends 关键字
  • super() 方法用于调用父类的构造函数
class Site {
  constructor(name) {
    this.sitename = name;
  }
}
 
class Runoob extends Site {
  constructor(name, age) {
    super(name);
    this.age = age;
  }

getter 和 setter

class Runoob {
  constructor(name) {
    this._sitename = name;
  }
  set sitename(x) {
    this._sitename = x;
  }
  get sitename() {
    return this._sitename;
  }
}

let noob = new Runoob("菜鸟教程");
noob.sitename = "RUNOOB";

静态方法

  • 使用 static 关键字修饰的方法,又叫类方法
class Runoob {
  constructor(name) {
    this.name = name;
  }
  static hello() {
    return "Hello!!";
  }
}
 
let noob = new Runoob("菜鸟教程");
 
// 可以在类中调用 'hello()' 方法
document.getElementById("demo").innerHTML = Runoob.hello();
 
// 不能通过实例化后的对象调用静态方法
// document.getElementById("demo").innerHTML = noob.hello();
// 以上代码会报错

JavaScript HTML DOM

查找 HTML 元素

  • 通过 id 找到 HTML 元素
    document.getElementById()
  • 通过标签名找到 HTML 元素
    getElementsByTagName("div")
  • 通过类名找到 HTML 元素
    document.getElementsByClassName("intro")

改变 HTML 内容

document.getElementById(id).innerHTML=新的 HTML

改变 HTML 属性

document.getElementById(id).attribute=新属性值

改变 HTML 样式

document.getElementById(id).style.property=新样式


DOM 事件

onload 和 onunload 事件

  • onload 和 onunload 事件会在用户进入或离开页面时被触发

onchange 事件

  • onchange 事件常结合对输入字段的验证来使用

onmouseover 和 onmouseout 事件

  • onmouseover 事件可用于在用户的鼠标移至元素上方时触发函数。
  • onmouseout 事件可用于在用户的鼠标移出元素时触发函数

onmousedown、onmouseup 以及 onclick 事件

  • 首先当点击鼠标按钮时,会触发 onmousedown 事件
  • 当释放鼠标按钮时,会触发 onmouseup 事件
  • 当完成鼠标点击时,会触发 onclick 事件

DOM EventListener

添加事件监听

  • addEventListener() 方法用于向指定元素添加事件句柄
    element.addEventListener(event, function, useCapture);
    • 第一个参数是事件的类型 (如 “click” 或 “mousedown”)
    • 第二个参数是事件触发后调用的函数
    • 第三个参数是个布尔值用于描述事件是冒泡还是捕获,该参数是可选的

事件传递方式

  • 冒泡
    • 存在两个点击事件时,内部元素的事件会先被触发,然后再触发外部元素
  • 捕获
    • 存在两个点击事件时,外部元素的事件会先被触发,然后才会触发内部元素的事件
  • useCapture 默认值为 false, 即冒泡传递,当值为 true 时, 事件使用捕获传递

移除事件监听

  • removeEventListener() 方法移除由 addEventListener() 方法添加的事件句柄
    element.removeEventListener("mousemove", myFunction);

JavaScript 对象

创建 JavaScript 对象

  • 使用 Object
// 使用Object创建对象实例
person=new Object();
person.firstname="John";
person.lastname="Doe";
person.age=50;
person.eyecolor="blue";
// 使用对象字面量创建对象
person={firstname:"John",lastname:"Doe",age:50,eyecolor:"blue"};
  • 使用构造函数
function person(firstname,lastname,age,eyecolor)
{
    this.firstname=firstname;
    this.lastname=lastname;
    this.age=age;
    this.eyecolor=eyecolor;
}

var myFather=new person("John","Doe",50,"blue");
  • 使用prototype给构造函数添加属性
function Person(first, last, age, eyecolor) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eyecolor;
}
// 直接添加会报错 Person.nationality = "English";
Person.prototype.nationality = "English";

事件循环 loop

事件队列: 异步代码的执行,遇到异步事件不会等待它返回结果,而是将这个事件挂起,继续执行执行栈中的其他任务。当异步事件返回结果,将它放到事件队列中,被放入事件队列不会立刻执行起回调,而是等待当前执行栈中所有任务都执行完毕,主线程空闲状态,主线程会去查找事件队列中是否有任务,如果有,则取出排在第一位的事件,并把这个事件对应的回调放到执行栈中,然后执行其中的同步代码。