主要功能
语言组成
ECMAScript,描述了该语言的语法和基本对象。
文档对象模型(DOM),描述处理网页内容的方法和接口。
浏览器对象模型(BOM),描述与浏览器进行交互的方法和接口。
运行模式
JavaScript是一种属于网络的高级脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。通常JavaScript脚本是通过嵌入在HTML中来实现自身的功能的。
语言特点
JavaScript脚本语言具有以下特点:
(1)脚本语言。JavaScript是一种解释型的脚本语言,C、C++等语言先编译后执行,而JavaScript是在程序的运行过程中逐行进行解释。
(2)基于对象。JavaScript是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象。
(3)简单。JavaScript语言中采用的是弱类型的变量类型,对使用的数据类型未做出严格的要求,是基于Java基本语句和控制的脚本语言,其设计简单紧凑。
(4)动态性。JavaScript是一种采用事件驱动的脚本语言,它不需要经过Web服务器就可以对用户的输入做出响应。在访问一个网页时,鼠标在网页中进行鼠标点击或上下移、窗口移动等操作JavaScript都可直接对这些事件给出相应的响应。
(5)跨平台性。JavaScript脚本语言不依赖于操作系统,仅需要浏览器的支持。因此一个JavaScript脚本在编写后可以带到任意机器上使用,前提是机器上的浏览器支持JavaScript脚本语言,JavaScript已被大多数的浏览器所支持。 [6]不同于服务器端脚本语言,例如PHP与ASP,JavaScript主要被作为客户端脚本语言在用户的浏览器上运行,不需要服务器的支持。所以在早期程序员比较倾向于使用JavaScript以减少对服务器的负担,而与此同时也带来另一个问题,安全性。
而随着服务器的强壮,虽然程序员更喜欢运行于服务端的脚本以保证安全,但JavaScript仍然以其跨平台、容易上手等优势大行其道。同时,有些特殊功能(如AJAX)必须依赖JavaScript在客户端进行支持。
编译模式
JavaScript是一种脚本语言,其源代码在发往客户端运行之前不需经过编译,而是将文本格式的字符代码发送给浏览器由浏览器解释运行。直译语言的弱点是安全性较差,而且在JavaScript中,如果一条运行不了,那么下面的语言也无法运行。而其解决办法就是于使用try{}catch(){},其中,catch()中会传入错误信息。
1console.log("a");//这是正确的 2 console.log("b");//这是正确的 3 console.logg("c");//这是错误的,并且到这里会停下来 4 console.log("d");//这是正确的 5 console.log("e");//这是正确的 6 7 /*解决办法*/ 8 try{console.log("a");}catch(e){}//这是正确的 9 try{console.log("b");}catch(e){}//这是正确的 10 try{console.logg("c");}catch(e){}//这是错误的,但是到这里不会停下来,而是跳过 11 try{console.log("d");}catch(e){}//这是正确的 12 try{console.log("e");}catch(e){}//这是正确的 13
JavaScript被归类为直译语言,因为主流的引擎都是每次运行时加载代码并解译。V8是将所有代码解译后再开始运行,其他引擎则是逐行解译(SpiderMonkey会将解译过的指令暂存,以提高性能,称为实时编译),但由于V8的核心部分多数用JavaScript撰写(而SpiderMonkey是用C++),因此在不同的测试上,两者性能互有优劣。与其相对应的是编译语言,例如C语言,以编译语言编写的程序在运行之前,必须经过编译,将代码编译为机器码,再加以运行。
注释://被称作行注释,/* */中的内容会被注释。
语言标准
JavaScript已经被Netscape公司提交给ECMA制定为标准,称之为ECMAScript,标准编号ECMA-262。最新版为ECMAScript 6。符合ECMA-262 3rd Edition标准的实现有:
Microsoft公司的JScript.
Mozilla的JavaScript-C(C语言实现),现名SpiderMonkey
Mozilla的Rhino(Java实现)
Digital Mars公司的DMDScript
Google公司的V8
版本记录
版本 | 发布日期 | 基于 | Netscape Navigator | Mozilla Firefox | Internet Explorer | Opera | Safari | Google Chrome |
---|---|---|---|---|---|---|---|---|
1.0 | 1996年3月 | - | 2.0 | - | - | - | - | - |
1.1 | 1996年8月 | - | 3.0 | - | 3.0 | - | - | - |
1.2 | 1997年6月 | - | 4.0-4.05 | - | - | - | - | - |
1.3 | 1998年10月 | ECMA-262 1 edition / ECMA-262 2 edition | 4.06-4.7x | - | 4.0 | - | - | - |
1.4 | - | - | NetscapeServer | - | - | - | - | - |
1.5 | 2000年11月 | ECMA-262 3 edition | 6.0 | 1.0 | 5.5 (JScript 5.5),6 (JScript 5.6),7 (JScript 5.7),8 (JScript 6) | 6.0,7.0,8.0,9.0 | - | - |
1.6 | 2005年11月 | 1.5 + Array extras + Array and String generics + E4X | - | 1.5 | - | - | 3.0,3.1 | - |
1.7 | 2006年10月 | 1.6 + Pythonic generators + Iterators + let | - | 2.0 | - | - | 3.2,4.0 | 1.0 |
1.8 | 2008年6月 | 1.7 + Generator expressions + Expression closures | - | 3.0 | - | 11.50 | - | - |
1.8.1 | - | 1.8 + Native JSON support + Minor Updates | - | 3.5 | - | - | - | - |
1.8.2 | 2009年6月22日 | 1.8.1 + Minor updates | - | 3.6 | - | - | - | - |
1.8.5 [11] | 2010年7月27日 | 1.8.1 + ECMAScript 5 Compliance | - | 4 | 9 | 11.60 | - | - |
ES2015 | 2015年 | ECMAScript 2015 | - | - | - | - | - | - |
版本 | 说明 | 实现 |
---|---|---|
ECMAScript 1 | 标准化了JavaScript1.1的基本特性,并添加了一些新特性。没有标准化switch语句和正则表达式。 | 由Netscape 4.5和IE 4实现。 |
ECMAScript 2 | ECMA v1的维护版本,只添加了说明 | 由Netscape 4.5和IE 4实现。 |
ECMAScript 3 | 标准化了switch语句、异常处理和正则表达式。 | 由Mozilla、Netscape 6和IE 5.5实现。 |
ECMAScript 5 | 添加了“严格模式”。添加了JSON支持。添加了String.trim()。添加了Array.isArray()。添加了数组迭代方法。 | - |
ECMAScript 5.1 | 编辑改变 | - |
ECMAScript 2015 | 添加了let和const添加了默认参数值添加了Array.find()添加了Array.findIndex() [4] | - |
ECMAScript 2016 | 添加了指数运算符(**)。添加了Array.prototype.includes [4] | - |
ECMAScript 2017 | 添加了字符串填充。添加了新的Object属性。添加了异步功能。添加了共享内存。 [4] | - |
ECMAScript 2018 | 添加了rest/spread属性。添加了异步迭代。添加了Promise.finally()。增加RegExp。 [4] | - |
js例子
外部引用
<script src="./06-外部.js"></script> <script>
内部引用
<script> document.write('你好,javascript') console.log('aaa') </script>
常用的案例
<script> document.write('我是js插入的语句') // 控制台输出语句 console.log('你真6')
// alert 警示框 alert('警告,你小子立即退出') // 输入语句 输入框 prompt('请输入您的年龄')
</script>
变量
// prompt('请输入您的用户名:')
// 变量:存储数据的容器 盒子
// 声明变量 let 变量名
let uname
// 变量赋值
uname = 'gouxin'
// 变量的初始化
let age = 18
console.log(age)
// 改变变量
uname = 'xianyanbao'
console.log(uname)
// 同时声明多个变量
let a = 1, b = 2
console.log(a, b)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // prompt('请输入您的用户名:') // 变量:存储数据的容器 盒子 // 声明变量 let 变量名 let uname // 变量赋值 uname = 'gouxin' // 变量的初始化 let age = 18 console.log(age) // 改变变量 uname = 'xianyanbao' console.log(uname) // 同时声明多个变量 let a = 1, b = 2 console.log(a, b) </script> </body> </html>
用户名输入案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> let uname = prompt('请输入用户名:') document.write(uname) </script> </body> </html>
var
使用
var
声明的变量将在任何代码执行前被创建,这被称为变量提升。这些变量的初始值为undefined
。缺点:不存在块级作用域 可以先使用,后声明 多次声明同一变量
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // var a = 12 // let b = 22 // var 不存在块级作用域 可以先使用,后声明 多次声明同一变量 // console.log(uname) // var uname = 'gouxin' // var uname = 'zs' // console.log(uname) // let uname = 'gouxin' // let uname = 'zs' </script> </body> </html>
常量(const)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 常量:存储的数据不能再变化 const 常量名 const GENDER = 'nv' // GENDER = '男' console.log(GENDER) </script> </body> </html>
基本数据类型(typeof)
对于javascript弱数据类型语言,只有进行赋值了,才知道是什么数据类型
// 字符串string类型 ' ' " "
// typeof 检测数据类型的方法
console.log(typeof (a))
// 字符串的拼接 +
let uname = 'zs'
let age = 21
document.write('姓名是:{uname}' + uname + '年龄是:' + age)
模板字符串
let uname = prompt('请输入用户名:')
let password = prompt('请输入密码:')
document.write(
<h1>用户名是:${uname},密码是:${password}</h1>
)let a =
gouxin
console.log(typeof (a))
其他类型
let num = 1
// 布尔类型 true false
console.log(2 > 3)
// undefined 未定义
console.log(uname)
var uname = 'zs'
// null 空的
// NAN not a number
console.log(undefined + 1) //nan
console.log(null + 1)
数据类型转换
// 隐式转换
// let a = 2
// let b = '3'
// console.log(a + b)
// 显式转换 Number(str) +
// let num1 = Number(prompt('请输入数字1:'))
// let num2 = Number(prompt('请输入数字2:'))
// let num1 = +prompt('请输入数字1:')
// let num2 = +prompt('请输入数字2:')
// console.log(num1 + num2)
// parseInt parseFloat 尽可能将字符串转换为数字类型
let c = 3.1415826
let d = '200.22px'
console.log(parseInt(d))
console.log(parseFloat(d))
运算符
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> 16-运算符 <script> let a = 3 let b = 5 // + - * / % console.log(a + b) console.log(b - a) console.log(b * a) console.log(b / a) // % 取余 console.log(b % a) a += 3 //a = a + 3 console.log(a) a -= 3 //a = a - 3 a *= 3 a /= 3 // 赋值运算符的优先级高于后减减,因此,先赋值,后运算 // let c = b-- // 自增 自减 // 前减减的优先级大于赋值运算符,因此,先减减,再赋值 let c = --b console.log(c) let d = c++ console.log(d) console.log(c) //5 let f = ++c console.log(f) </script> </body> </html>
比较运算符
// let a = 4
// let b = 5
// console.log(a > b)
// console.log(a >= b)
// console.log(a < b)
// console.log(a <= b)
// console.log(a = b) = 赋值运算符
console.log(3 == '3') // == :等于 只判断值 有隐式转换,把字符串转换为数字类型
console.log(3 === '3') //===:全等 判断值、数字类型是否都一致
逻辑运算符
<script> // && :两真才真,一假则假 console.log(3 > 2 && 2 > 4) // 或 || : 一真则真,两假才假 console.log(3 > 2 || 2 > 4) // 非 ! 取反 console.log(!(3 > 2))
</script>
单分支语句
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> let age = +prompt('请输入你的年龄:') // if(判断条件){ // 执行代码块 // } if (age > 18) { alert('欢迎光临,你成年了~') } </script> </body> </html>
双分支语句
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> let age = +prompt('请输入您的年龄') // if (条件语句1) { // 执行代码块1 // } else { // 执行代码块2 // } if (age > 18) { alert('你成年了思密达~') } else { alert('小屁孩,边儿去~') } </script> </body> </html>
多分支语句
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> let score = +prompt('请输入你的成绩:') // if (条件1) { // 代码块1 // } // else if (条件2) { // 代码块2 // } // else if (条件三) { // 代码块3 // } else { // } if (score <= 60) { alert('脑子呢??') } else if (score <= 80) { alert('还不错,继续努力就及格了') } else if (score <= 120) { alert('再接再厉,牛的') } else { alert('你已经是大神了,慕白你') } </script> </body> </html>
判断平闰年
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- year%4===0&&year%100!==0||year%400===0 --> <script> let year = +prompt('请输入年份:') // if (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0) { // alert(`${year}是闰年`) // } else { // alert(`${year}是平年`) // } year % 4 === 0 && year % 100 !== 0 || year % 400 === 0 ? alert(`${year}是闰年`) : alert(`${year}是平年`) </script> </body> </html>
三元运算符
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 判断条件 ? 成立时执行的代码 : 不成立时执行的代码 // 三元运算符 双分支的简写 // if (3 > 5) { // alert('这个世界疯了') // } else { // alert('你是不是个der') // } 3 < 5 ? alert('这个世界疯了') : alert('你是不是个der') </script> </body> </html>
switch语句
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> let week = prompt('请输入今天星期几了') switch (week) { case "1": alert('今天星期一,猴子穿大衣~') break case "2": alert('今天星期二,猴子有点二') break case "3": alert("今天星期三,猴子去爬山") break case "4": alert("今天星期四,猴子要找事") break case "5": alert("今天星期五,猴子打老虎") break case "6": case "7": alert("今天周末,休假") break default://无符合条件时,执行的代码 alert("你是猴子派来的救兵吧~~~") break } </script> </body> </html>
for循环
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // console.log('我爱你') // console.log('我爱你') // console.log('我爱你') // console.log('我爱你') // console.log('我爱你') // console.log('我爱你') // console.log('我爱你') // console.log('我爱你') for (let i = 0; i < 100; i++) { console.log('我爱你') } </script> </body> </html>
练习
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> let sum = 0 for (let i = 1; i <= 100; i++) { if (i % 2 === 0) { sum += i//sum=sum+i } } alert(sum) </script> </body> </html>
while循环
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> let i = 1 while (i <= 10) { console.log(i) i++ } // while (true) { // let n = prompt('你爱我吗?') // if (n === "爱") { // break // } // } alert(true === 1) </script> </body> </html>
do……while循环
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // let i = 11 // while (i <= 10) { // console.log(i) // i++ // } let j = 11 do { console.log(j) j++ } while (j <= 10) </script> </body> </html>
break、continue
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> for (let i = 0; i < 100; i++) { if (i === 50) { continue //退出本次循环 } if (i === 70) { break//退出循环 } console.log(i) } </script> </body> </html>
循环嵌套
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> /* span { display: inline-block; background-color: pink; } */ </style> </head> <body> <script> for (let i = 1; i < 8; i++) { console.log(`今天是第${i}天`); for (let j = 1; j <= 10; j++) { console.log(`这是我送的第${j}朵花`) } } for (let i = 1; i <= 5; i++) { for (let j = 1; j <= i; j++) { document.write(`<span>*</span>`) } document.write(`<br/>`) } </script> </body> </html>
数组
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> //存储多个数据的容器-数组 // 声明方式: [] 数组存在数组下标,从0开始 let arr = ['gouxin', 'liuxingyun', 'xainyanbao', 'wangwu'] console.log(arr) // 查找 数组名[数组下标] console.log(arr[1]) </script> </body> </html>
循环加强
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // for in for of let arr = [1, 2, 3, 4, 5, 6, 7, 'gouxin', true] // for (let i in arr) { // // console.log(i) // console.log(arr[i]) // } for (let k of arr) { console.log(k) } </script> </body> </html>
函数
函数它内部封装了一些操作,只有我们去调用的时候才会执行
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>我的第一个方法</title> </head> <body> <button οnclick="myFunction()">点击触发函数</button> <script> // 必须有 function关键字,命名通常为驼峰命名,首字母小写 function myFunction(){ alert("这是我的函数"); } </script> </body> </html>
函数传参
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 函数小括号里用于接受实参的叫做形参 function sayHi(msg) { console.log(`用户说:${msg}`) } // 函数调用时,传进去的参数,叫做实参 sayHi('今天天气真好,狂风暴雨') // 求和函数 function getSum(a, b) { console.log(a + b) } getSum(2, 3) </script> </body> </html>
函数返回值
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> let arr = [11, 22, 12, 33, 4, 34] function getSum(arr) { let sum = 0 for (let i = 0; i < arr.length; i++) { sum += arr[i] } // console.log(sum) // 返回值:return return sum // console.log('111') } // 函数没有返回值,默认返回undefined return 结束函数的作用,之后的代码不会再执行 let a = getSum(arr) document.write(a) </script> </body> </html>
值传递和引用传递
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 将自身的值传进函数 let a = 11 let b = 22 function change(x, y) { x = 21 y = 33 } change(a, b) console.log(a, b) // 数组:引用数据类型,将自己的地址传递给函数 let arr = [1, 2, 3, 4, 5] function change2(arr) { arr.push(100) } change2(arr) console.log(arr) </script> </body> </html
默认值参数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 默认值参数:在形参的最后 function area(r, PI = 3.14) { return PI * r * r } let a = area(2) console.log(a) </script> </body> </html>
arguements
function.arguments 属性代表传入函数的实参,它是一个类数组对象。 function.arguments 已经被废弃了,现在推荐的做法是使用函数内部可用的 arguments 对象来访问函数的实参。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // function getSum(a, b) { // return a + b // } // getSum(2, 3, 55, 4, 3, 2, 2) // arguements function getSum() { // arguments伪数组 // console.log(arguments) let sum = 0 for (let i = 0; i < arguments.length; i++) { sum += arguments[i] } return sum } let a = getSum(1000, 1, 2, 3, 4, 5, 6, 7, 8, 9) console.log(a) </script> </body> </html>
匿名函数
1、函数表达式
let fn = function () { console.log("你好") }
fn()
普通的具名函数,可以在声明前去使用,而函数表达式,只能先声明,后使用
2、立即执行函数
let num=1
let num=2
(function () {
let num = 1
console.log(num)
}())
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> //具名函数 匿名函数:没有名字的函数 // say() // function say() { // console.log('good') // } // 1、函数表达式 // let fn = function () { console.log("你好") } // fn() // 普通的具名函数,可以在声明前去使用,而函数表达式,只能先声明,后使用 // 2、立即执行函数 // let num=1 // let num=2 // (function () { // let num = 1 // console.log(num) // }()) (function () { console.log('121212') })() </script> </body> </html>
作用域
作用域:一段代码中所用到的名字不是一直有效且可用的,而限制这个名字可用范围的就是这个名字的作用域
减少名字冲突 不同作用域之间相互不影响
全局作用域 局部作用域 :函数内部声明的变量
script里边,函数外边声明的变量
全局变量 :script里边,函数外边声明的变量 局部变量:函数内声明的变量(外部不能访问)
函数的形参也可以理解为局部变量
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> let a = 1 for (let i = 0; i < 9; i++) { console.log(i) } for (let i = 7; i < 10; i++) { console.log(i) } // console.log(i) // 作用域:一段代码中所用到的名字不是一直有效且可用的,而限制这个名字可用范围的就是这个名字的作用域 // 减少名字冲突 不同作用域之间相互不影响 // 全局作用域 局部作用域 :函数内部声明的变量 // script里边,函数外边声明的变量 // 全局变量 :script里边,函数外边声明的变量 局部变量:函数内声明的变量(外部不能访问) // 函数的形参也可以理解为局部变量 function say() { let num = 33 console.log(a) } say() console.log(num) </script> </body> </html>
递归
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 递归:把一个问题,尽可能的拆分成小问题,知道不能拆分 // 9! // 9*8! // 9*8*7! // 9*8*7*6*5*4*3*2*1! function jiecheng(n) { if (n === 1) { return 1 } return n * jiecheng(n - 1) } let a = jiecheng(9) console.log(a) </script> </body> </html>
闭包
一、定义:一种解决问题的办法,一种特殊结构 ,一种机制。 1.包含两层含义要执行的代码块(自有对象机子有对象引用的对象)和自由变量的作用域。 2.当一个嵌套的内部函数引用了外部函数的变量或函数时,即产生闭包 二、作用:仅能使变量重用又能保护变量不被污染 1.使用函数内部的变量再函数执行完后,仍然存活在内存中(延长了局部变量的生命周期)
2.让函数在外部可以操作(读写)到函数内部的数据(变量/函数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> function outer() { let money = 100 function inner() { console.log(money) } return inner } let a = outer() a() console.log(money) </script> </body> </html>
对象
声明方法: let 对象名={} let 对象名=new Object()
对象:属性和方法 属性:信息或者特征 方法:行为或者动作 打电话、玩游戏……
// 查:对象名.属性名
console.log(obj.age)
console.log(obj.uname)
// 查找2.0 对象名['属性名(string)']
console.log(obj['gender'])
// 增 对象.新属性=属性值
obj.like = '王者荣耀'
// 改
obj.uname = 'zs'
// 删
delete obj.gender
console.log(obj)
对象遍历
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> let obj = { uname: 'gouxin', age: 21, gender: 'nv', sing: function () { console.log('我要唱歌了,请保护你的耳朵') } } for (let k in obj) { // console.log(typeof (k)) console.log(obj[k]) } </script> </body> </html>
Math模块
-
**Math 是一个内置对象,它拥有一些数学常数属性和数学函数方法。
-
*Math 不是一个函数对象。 Math 用于 Number 类型。它不支持 BigInt。 *
-
与其他全局对象不同的是,Math 不是一个构造器。
-
Math 的所有属性与方法都是静态的。
-
引用圆周率的写法是 Math.PI,
-
调用正余弦函数的写法是 Math.sin(x),x 是要传入的参数。Math 的常量是使用 JavaScript 中的全精度浮点数来定义的。
-
Math.abs(x) 返回一个数的绝对值。
-
Math.acos(x) 返回一个数的反余弦值。 Math.acosh(x) 返回一个数的反双曲余弦值。**
-
Math.asin(x) 返回一个数的反正弦值。…*
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> console.dir(Math) // console.log(Math) console.log(Math.E) console.log(Math.PI) // ceil()向上取整 console.log(Math.ceil(3.1415)) // floor()向下取整 console.log(Math.floor(3.1415)) // abs取绝对值 console.log(Math.abs(-3.1415)) // pow console.log(Math.pow(2, 3)) console.log(Math.random()) //[0,1)之间的随机数 let arr = ['zs', 'ls', 'ww', 'gouxin', 'heidashuai'] let random = Math.floor(Math.random() * 5) document.write(arr[random]) </script> </body> </html>
时间模块
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // new关键字,就是在实例化 // console.log(date) let date = new Date() console.dir(date) function getTime() { let y = date.getFullYear() let m = date.getMonth() + 1 let d = date.getDate() let hh = date.getHours() let mm = date.getMinutes() let ss = date.getSeconds() let week = date.getDay() // 补零: m = m < 10 ? '0' + m : m d = d < 10 ? '0' + d : d hh = hh < 10 ? '0' + hh : hh mm = mm < 10 ? '0' + mm : mm ss = ss < 10 ? '0' + ss : ss return `${y}年-${m}月-${d}日 ${hh}:${mm}:${ss} 星期${week}` } let a = getTime() console.log(a) </script> </body> </html>
字符串对象
console.log(typeof (str)) // length 属性 console.log(str.length) // split()将字符串分隔为数组并返回 let a = str.split('a') console.log(a) // endsWith startsWith str.startsWith('nihao') console.log(str.startsWith('dcnd')) // indexOf 字符串中是否包含某字符 str.indexOf('gouxin') console.log(str.indexOf('gouxin'))**
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> let str = new String() str = 'nihao,huanyingjiaru web' console.log(typeof (str)) // length 属性 console.log(str.length) // split()将字符串分隔为数组并返回 let a = str.split('a') console.log(a) // endsWith startsWith str.startsWith('nihao') console.log(str.startsWith('dcnd')) // indexOf 字符串中是否包含某字符 str.indexOf('gouxin') console.log(str.indexOf('gouxin')) // match 匹配字符串,支持正则 let c = str.match(/a/g) console.log(c) // replace 查找、替换,支持正则匹配 let f = str.replace('huanying', 'jujueni') console.log(f) </script> </body> </html>
构造函数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // let str=new String() // let obj = { // uname: 'linjunjie', // age: 31, // sing: function () { // console.log('我要唱歌了') // } // } // let obj2 = { // uname: 'zhnagjei', // age: 33, // sing: function () { // console.log('我要唱歌了') // } // } // 构造函数的基本格式 一个模板 function Obj(uname, age) { this.uname = uname, this.age = age, this.sing = function () { console.log('我要唱歌了') } } // 实例化对象 let str = '' // let str = new String() // let arr = new Array() let obj1 = new Obj('zhangjie', 21) console.log(obj1) obj1.sing = function () { console.log('sing') } obj1.sing() let obj2 = new Obj('linjunjie', 33) console.log(obj2) obj2.sing() </script> </body> </html>
原型对象
一、什么是原型
原型是继承中的基础,JavaScript的继承就是基于原型的继承。
JavaScript原型是指为其他对象提供共享属性访问的对象。在创建对象时,每个对象都包含一个隐式引用指向它的原型对象或者null。
原型对象也是对象,这个对象也有自己的原型对象,我们称为原型对象的原型对象。这样就构成一个原型链。
二、函数的原型对象
我们在创建函数的同时,浏览器会在内存中创建一个对象。这个函数中默认有一个prototype属性,指向了该对象。这个对象就是函数的原型对象,简称函数的原型。
每个构造函数都有一个原型对象存在,这个原型对象通过构造函数的prototype属性来访问。原型对象默认会有一个constructor属性指向构造函数。
三、原型的相关属性及方法
1、prototype属性
prototype是函数独有的,存在于构造函数中,它是从一个函数指向一个对象。
它的含义是函数的原型对象,也就是这个函数所创建的实例的原型对象。
它的作用是包含可以由特定类型的所有实例共享的属性和方法。
##
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> function Obj(uname, age) { this.uname = uname, this.age = age } // Obj.prototype.sing = function () { // console.log('我要唱歌了') // } Obj.prototype = { // 原型对象中的constructor被覆盖丢失。重新指回去:constructor:Obj, constructor: Obj, sing: function () { console.log('我要唱歌了') }, dance: function () { console.log('我要跳舞') } } console.dir(Obj) let obj1 = new Obj('zs', 18) obj1.sing() console.log(obj1.__proto__ === Obj.prototype) let obj2 = new Obj('ls', 22) obj2.sing() // 对象:都具有prototype的属性,即都有原型对象,而原型对象本身又是对象 // javascript里:万物皆对象 // let arr1=[] // let arr = new Array() // console.log(arr) </script> </body> </html>
2、constructor属性
constructor属性是对象所拥有的,它是从一个对象指向一个函数。
3、proto 属性
proto属性是对象所独有的,它是从一个对象指向一个对象,也即指向它们的原型对象。
它的作用是当访问一个对象的属性时,如果该对象内部不存在这个对象,那么就会去它的proto属性所指向的那个对象(即父对象)里面找,如果父对象也不存在这个属性,则继续往父对象的proto属性所指向的那个对象里面找,如果还没找到,就继续往上找,直到原型链顶端null。
4、hasOwnProperty() 方法
它的作用是判断函数的原型所在位置。一个对象本身添加的属性返回true,在原型中的属性和不存在的属性都会返回false。
以上属性及方法简单例子:
//创建构造函数
function Person(){}
//使用Person.prototype直接访问到原型对象
// 给Person函数的原型对象中添加一个属性name,值是"小明"
// Person.prototype.name = "小明";
Person.prototype = {
constructor:Person, //让constructor重新指向Person函数 /*如果直接给Person的原型指定对象字面量(没有上面这一行), 这个对象的constructor属性不再指向Person函数*/ name: "小明"
};
//创建一个实例对象p1
var p1 = new Person();
//访问p1对象的属性name
p1.age = 18;
console.log(Person.prototype.constructor === Person);
//输出结果是:true
//如果在Person.prototype中没有constructor:Person这一行代码则输出flase
//Person.prototype.name = "小明";这种写法输出也是true
console.log(p1.proto=== Person.prototype);
//输出结果是:true
//如果在Person.prototype中没有constructor:Person这一行代码则输出flase
//Person.prototype.name = "小明";这种写法输出也是true
console.log(p1.name);
//输出结果是:小明
/*虽然在p1对象中没有明确的添加属性name,但是仍然可以成功打印的原因是:
p1的proto属性指向的原型中有name属性,所以可以访问到属性name值。*/
console.log(p1.hasOwnProperty("age"));
//输出结果是:true
//因为age属性是直接在p1属性中添加的
console.log(p1.hasOwnProperty("name"));
//输出结果是:false
//因为name属性是在原型中添加的
console.log(p1.hasOwnProperty("sex"));
//输出结果是:false
//因为sex属性不存在
四、构造函数、原型对象、实例对象的关系
构造函数、原型对象、实例对象的关系:
①每个构造函数都有一个prototype属性,这个属性指向了原型对象。
②每个实例对象都有一个proto属性,这个属性指向了对象的原型对象。
③在原型对象里有一个constructor属性,该属性指向了构造函数。
三者关系示意图如下:
获取元素
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <button></button> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> </ul> <div class="box">11111</div> <input type="text"> <script> // 1、通过css选择器获取 document.querySelector只获取满足条件的第一个元素对象 (倾情推荐) // document.querySelector('css选择器') const btn = document.querySelector('button') // console.log(typeof (btn)) console.dir(btn) const li = document.querySelector('ul li') console.log(li) // document.querySelectorAll将所有的满足条件的元素对象获取并保存至伪数组 const lis = document.querySelectorAll('ul li') console.log(lis) // 2、class名 let box = document.getElementsByClassName('box') console.log(box) // 3、标签名 let input = document.getElementsByTagName('input') console.log(input) // 4、id // document.getElementById('') </script> </body> </html>
修改dom元素内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div>我是一个盒子</div> <script> // 1、获取元素 let div = document.querySelector('div') // 2、修改元素内容 // 1、innerText() 无法识别标签 div.innerText = `<h1>我被修改过</h1>` // 2、innerHtml() 可以识别标签 (热烈推荐) div.innerHTML = '<h1>我又又又被改了</h1>' </script> </body> </html>
tab栏切换
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; } .box { width: 1200px; margin: 0 auto; } .top ul { display: flex; } .top ul li { list-style: none; width: 70px; height: 50px; border: 1px solid pink; } .dixia { position: relative; } .goods { display: none; position: absolute; top: 0; left: 0; width: 800px; height: 500px; border: 1px solid black; } .dixia .goods:nth-child(1) { background-color: pink; } .dixia .goods:nth-child(2) { background-color: green; } .dixia .goods:nth-child(3) { background-color: blue; } .dixia .goods:nth-child(4) { background-color: black; } .active { display: block; } </style> </head> <body> <div class="box"> <div class="top"> <ul> <li><a href="#">粉色</a></li> <li><a href="#">绿色</a></li> <li><a href="#">蓝色</a></li> <li><a href="#">黑色</a></li> </ul> </div> <div class="dixia"> <div class="goods"></div> <div class="goods"></div> <div class="goods"></div> <div class="goods"></div> </div> </div> <script> </script> </body> </html>