文章目录
JavaScript
严格检查模式use strict
通过在脚本或函数的开头添加"use strict"
; 来声明严格模式。
在脚本开头进行声明,拥有全局作用域(脚本中的所有代码均以严格模式来执行,如果该句不在首行,则无效)
将’use strict’放在函数第一行,表示整个函数为’严格模式’,函数以外在为正常模式;
<script>
// 开启严格检查模式
"use strict"; // 必须写在第一行
i = 1;
console.log(i); // 报错 i is not defined
</script>
// 两个不同的script块都需要书写
<script>
// 未开启严格检查模式
j = 1;
console.log(j); // 正常输出
</script>
字符串
模板字符串
// 支持字符串插值
let name = "lucas"
let msg = `hello,${name}!`;
console.log(msg); // hello,lucas!
// 支持换行定义字符串
let str = `1
2
3`;
console.log(str);
输出:
1
2
3
字符串不变性
let str = "hello";
str[0] = 'H';
console.log(str); // hello
数组
创建方式
let arr = [1,2,3];
let arr = new Array(); //创建一个空数组[]
let arr = new Array(3); //创建一个长度为3的数组(数组项都为undefined)
let arr = new Array('a',1); //创建数组并写入数组元素 ['a',1]
类型不定、长度可变
let arr = [1,2,"a","b"];
console.log(arr); // [ 1, 2, 'a', 'b' ]
console.log(arr.length); // 4
arr.length = 5;
console.log(arr); // [ 1, 2, 'a', 'b', <1 empty item> ]
console.log(arr.length); // 5
arr[6] = '7';
console.log(arr); // [ 1, 2, 'a', 'b', <2 empty items>, '7' ]
arr.length = 1;
console.log(arr); // [ 1 ]
console.log(arr.length); // 1
常用方法
-
join
数组转字符串,将数组按指定拼接符拼接,返回string,原数组不改变let arr = [1,2,3]; let str = arr.join('-'); console.log(str); // 1-2-3 console.log(arr); // [ 1, 2, 3 ] console.log(typeof(str)); // string
-
push()
和pop()
(数组尾操作)push()
:向数组的末尾添加一个或多个元素,并返回新的长度。pop()
:用于删除并返回数组的最后一个元素。let arr = [1,2,3]; console.log(arr); // [ 1, 2, 3 ] console.log(arr.push(4,'a')); // 5 console.log(arr); // [ 1, 2, 3, 4, 'a' ] console.log(arr.pop()); // a console.log(arr); // [ 1, 2, 3, 4 ]
-
shift()
和unshift()
(数组首操作)unshift()
:向数组的开头添加一个或更多元素,并返回新的长度。shift()
:用于把数组的第一个元素从其中删除,并返回第一个元素的值。let arr = [1,2,3]; console.log(arr); // [ 1, 2, 3 ] console.log(arr.unshift(4,'a')); // 5 console.log(arr); // [ 4, 'a', 1, 2, 3 ] console.log(arr.shift()); // 4 console.log(arr); // [ 'a', 1, 2, 3 ]
-
sort()
(排序)let arr = [4,3,2,1]; console.log(arr.sort()); // [ 1, 2, 3, 4 ] console.log(arr); // [ 1, 2, 3, 4 ] 原数组改变 function cmp(a,b) { return b - a; } console.log(arr.sort(cmp)); // [ 4, 3, 2, 1 ] console.log(arr); // [ 4, 3, 2, 1 ] 原数组改变
-
reverse()
(反转数组)let arr=[1,2,3,4]; console.log(arr.reverse()); // [ 4, 3, 2, 1 ] console.log(arr); // [ 4, 3, 2, 1 ] 原数组改变
-
concat()
(连接两个或多个数组)concat()
方法用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。在没有给
concat()
方法传递参数的情况下,它只是复制当前数组并返回副本。let arr = [1,2,3,4]; let arr2 = [11,12,13,14]; let arrCopy = arr.concat(arr2); console.log(arr.concat()); // [ 1, 2, 3, 4 ] console.log(arrCopy); // [ 1, 2, 3, 4, 11, 12, 13, 14 ] console.log(arr); // [ 1, 2, 3, 4 ] 原数组未改变
-
slice()
(数组截取)arr.slice(start , end);
start
:必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。end
:可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。返回值:返回一个新的数组,包含从
start
到end
(不包括该元素)的arr
中的元素。let arr = [1,4,6,8,12]; let arrCopy1 = arr.slice(1); let arrCopy2 = arr.slice(0,4); let arrCopy3 = arr.slice(1,-2); let arrCopy4 = arr.slice(-5,4); let arrCopy5 = arr.slice(-4,-1) console.log(arrCopy1); // [ 4, 6, 8, 12 ] console.log(arrCopy2); // [ 1, 4, 6, 8 ] console.log(arrCopy3); // [ 4, 6 ] console.log(arrCopy4); // [ 1, 4, 6, 8 ] console.log(arrCopy5); // [ 4, 6, 8 ] console.log(arr); // [ 1, 4, 6, 8, 12 ]
-
splice()
(数组更新)splice()
方法向/从数组中添加/删除项目,然后返回被删除的项目。(该方法会改变原始数组)arr.splice(index , howmany , item1,.....,itemX)
index
:必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。howmany
:必需。要删除的项目数量。如果设置为 0,则不会删除项目。item1, ..., itemX
:可选。向数组添加的新项目。返回值:含有被删除的元素的数组,若没有删除元素则返回一个空数组。
let arr = ["张三","李四","王五","小明","小红"]; //删除"王五" let arrReplace1 = arr.splice(2,1); console.log(arrReplace1); // ["王五"] console.log(arr); // ["张三", "李四", "小明", "小红"] (原数组改变) //删除多个 let arrReplace2 = arr.splice(1,2); console.log(arrReplace2); // ["李四", "小明"] console.log(arr); // ["张三", "小红"] //添加"小刚" let arrReplace3 = arr.splice(1,0,"小刚"); console.log(arrReplace3); // [] (没有删除元素,所以返回的是空数组) console.log(arr); // ["张三", "小刚", "小红"] //添加多个 let arrReplace4 = arr.splice(3,0,"刘一","陈二","赵六"); console.log(arrReplace4); // [] console.log(arr); // ["张三", "小刚", "小红", "刘一", "陈二", "赵六"] //"王五"替换"小刚" let arrReplace5 = arr.splice(1,1,"王五"); console.log(arrReplace5); // ["小刚"] console.log(arr); // ["张三", "王五", "小红", "刘一", "陈二", "赵六"] //替换多个 let arrReplace6 = arr.splice(1,4,"李四"); console.log(arrReplace6); // ["王五", "小红", "刘一", "陈二"] console.log(arr); // ["张三", "李四", "赵六"]
函数
定义方式
let 函数名 = function(参数列表) {
// 可带return
}
实例:
let abs = function(x) {
return x > 0 ? x:-x;
}
function 函数名(参数列表) {
// 可带return
}
实例:
function abs(x) {
return x > 0 ? x:-x;
}
默认参数值
函数默认参数允许在没有值或undefined
被传入时使用默认形参。
function multiply(a, b = 1) {
return a * b;
}
console.log(multiply(5, 2)); // 10
console.log(multiply(5)); // 5
arguments关键字
arguments
是一个对应于传递给函数的参数的类数组对象。
arguments
对象是所有(非箭头)函数中都可用的局部变量。你可以使用arguments
对象在函数中引用函数的参数。
function fun(x,y) {
for (let i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
console.log(arguments);
}
fun(1,2);
fun(1,2,3,4);
输出:
1
2
[Arguments] { '0': 1, '1': 2 }
1
2
3
4
[Arguments] { '0': 1, '1': 2, '2': 3, '3': 4 }
rest语法
如果函数的最后一个命名参数以...
为前缀,则它将成为一个由剩余参数组成的真数组,只包含那些没有对应形参的实参。
function 函数名(参数名1,参数名2,...剩余参数参数名) {
}
function fun(x,y,...rest) {
console.log(rest);
}
fun(1,2); // []
fun(1,2,3,4,5,6); // [ 3, 4, 5, 6 ]
变量
不考虑兼容性的情况下,普通变量全部使用 let(ES6新特性),可以避免变量提升、重复声明变量、全局变量冲突等问题。
常量使用const(ES6新特性)声明。
let name = 'lucas';
const PI = 3.14
方法
在对象中的函数称为方法
let person = {
name:'lucas',
birthday:2000,
age:function() {
return new Date().getFullYear() - this.birthday;
}
}
console.log(person.age()); // 21
apply和call
-
apply()
和call()
通过
apply()
或者call()
方法,您能够编写用于不同对象的方法。它们能劫持一个对象的方法,继承另外一个对象的属性,简单来说就是改变函数体内部this的指向。let person = { fullName: function() { return this.firstName + " " + this.lastName; }, message: function(city, country) { return this.firstName + " " + this.lastName + "," + city + "," + country; } } let person1 = { firstName:"Bill", lastName: "Gates", } console.log(person.fullName.apply(person1)); // Bill Gates console.log(person.message.apply(person1, ["Oslo", "Norway"])); // Bill Gates,Oslo,Norway console.log(person.fullName.call(person1)); // Bill Gates console.log(person.message.call(person1,"Seattle", "USA")); // Bill Gates,Seattle,USA
-
call()
和apply()
之间的区别call()
方法分别接受参数。apply()
方法接受数组形式的参数。如果要使用数组而不是参数列表,则
apply()
方法非常方便。 -
apply
巧用console.log(Math.max(1,2,3)); // 3 console.log(Math.max([1,2,3])); // NaN 不接受数组参数 console.log(Math.max.apply(null,[1,2,3])); // 3 console.log(Math.max.apply(" ",[1,2,3])); // 3 console.log(Math.max.apply(Math,[1,2,3])); // 3
注意:在
JavaScript
严格模式下,如果apply()
方法的第一个参数不是对象,则它将成为被调用函数的所有者(对象)。在“非严格”模式下,它成为全局对象。
对象
声明方式
类型 对象名 = {
属性名:属性值,
属性名:属性值,
属性名:属性值
}
let person = {
name:"lucas",
age:21
}
动态增删属性
let person = {
name:"lucas",
age:21
}
console.log(person); // { name: 'lucas', age: 21 }
delete person.age; // 删除属性
console.log(person); // { name: 'lucas' }
person.hobby = "coding"; // 增加属性
console.log(person); // { name: 'lucas', hobby: 'coding' }
判断某个属性/方法是否属于对象
in
对象的自有属性或继承属性中包含这个属性则返回true
;hasOwnProperty
用来检测是否是对象自有属性,对于继承属性返回false
;
let person = {
name:"lucas",
age:21
}
/*
in 对象的自有属性或继承属性中包含这个属性则返回true;无论是key值name,还是原形链上的toString,都能检测到返回true。
*/
console.log("age" in person); // true
console.log("toString" in person); // true
/*
hasOwnProperty 用来检测是否是对象自有属性,对于继承属性返回false;原型链上继承过来的属性toString无法通过hasOwnProperty检测到,返回false。
*/
console.log(person.hasOwnProperty("age")); // true
console.log(person.hasOwnProperty("toString")); // false
面向对象
原型
… …
class与继承
在ES6 中引入了 class
关键字,但那只是语法糖,JavaScript 仍然是基于原型的。
class Student {
// 构造器
constructor(name) {
this.name = name;
}
hello() {
console.log(`hello,${this.name}`);
}
}
class PrimaryStudent extends Student {
constructor(name,grade) {
super(name);
this.grade = grade;
}
myGrade() {
console.log(`I am at grade ${this.grade}`);
}
}
let lucas = new Student('lucas');
lucas.hello(); // hello,lucas
let jack = new PrimaryStudent('jack',1);
jack.myGrade(); // I am at grade 1
BOM对象
BOM(Browser Object Mode)
浏览器对象模型,是Javascript
的重要组成部分。它提供了一系列对象用于与浏览器窗口进行交互,这些对象通常统称为BOM
。
window
顶级对象:所有全局变量是 window
对象的属性,全局函数是window 对象的方法。
window
对象有innerWidth
和innerHeight
属性,可以获取浏览器窗口的内部宽度和高度。内部宽高是指除去菜单栏、工具栏、边框等占位元素后,用于显示网页的净宽高。对应的,还有一个outerWidth
和outerHeight
属性,可以获取浏览器窗口的整个宽高。
window.innerHeight
754
window.innerWidth
638
window.outerHeight
824
window.outerWidth
1536
screen
screen
对象表示屏幕的信息,常用的属性有:
screen.width
:屏幕宽度,以像素为单位;screen.height
:屏幕高度,以像素为单位;screen.colorDepth
:返回颜色位数,如8、16、24。
screen.width
1536
screen.height
864
location
-
location
对象表示当前页面的URL信息。location.href // 获取完整的URL 例如:http://www.example.com:8080/path/index.html?a=1&b=2#TOP location.protocol; // 'http' location.host; // 'www.example.com' location.port; // '8080' location.pathname; // '/path/index.html' location.search; // '?a=1&b=2' location.hash; // 'TOP' location.assign(URL) // 加载一个新页面 location.reload() // 重新加载当前页面
document
document
对象表示当前页面。由于HTML在浏览器中以DOM形式表示为树形结构,document
对象就是整个DOM树的根节点。
document
的title
属性是从HTML文档中的<title>xxx</title>
读取的,但是可以动态改变。
Document.visibilityState
Document.visibilityState
(只读属性),返回document
的可见性,即当前可见元素的上下文环境。由此可以知道当前文档(即为页面)是在背后,或是不可见的隐藏的标签页,或者(正在)预渲染。
visible
: 此时页面内容至少是部分可见。即此页面在前景标签页中,并且窗口没有最小化。hidden
:此时页面对用户不可见。即文档处于背景标签页或者窗口处于最小化状态,或者操作系统正处于锁屏状态。prerender
:页面此时正在渲染中,因此是不可见的(considered hidden for purposes ofdocument.hidden
)。
当此属性的值改变时, 会递交 visibilitychange
事件给Document
。
document.addEventListener('visibilitychange',function(){
let isHidden = document.hidden;
if (isHidden) {
document.title = '你快回来~~~';
} else {
document.title = '你终于回来了!';
}
})
DOM
获得DOM结点
<div id="father">
<h1>一级标题1</h1>
<h1>一级标题2</h1>
<p class="paragraph">段落</p>
</div>
<script>
'use strict';
let father = document.getElementById('father'); // 单个
let h1 = document.getElementsByTagName('h1'); // 数组
let p =document.getElementsByClassName('paragraph'); // 数组
</script>
更新DOM结点
更新内容
-
innerHTML
可以写入HTML代码,写入的HTML代码可以被解析,获得时候也可以获得HTML代码。通过innerHTML进行赋值会清空所选标签内的所有内容后在进行赋值。
-
innerText
获得内容的时候,会忽略HTML代码,写入HTML代码不能解析。获得内容与HTML解析的内容一样。
-
textContent
获得内容的时候,会忽略HTML代码,写入HTML代码不能解析。获取的内容与源码内容一样。
-
value
value
是表单元素特有的属性,输入输出的是转义文本(字符串)`;非表单元素没有value属性。<!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 id="div"> 我是一个div </div> <script> let div = document.getElementById('div'); // " // 我是一个div // " console.log(div.innerHTML); console.log(div.innerText); // "我是一个div" // " // 我是一个div // " console.log(div.textContent); div.innerHTML = '<p>我是一个段落</p>'; console.log(div.innerHTML); // "<p>我是一个段落</p>" console.log(div.innerText); // "我是一个段落" console.log(div.textContent); // "我是一个段落" div.innerText = '<p>我是一个段落</p>'; console.log(div.innerHTML); // "<p>我是一个段落</p>" console.log(div.innerText); // "<p>我是一个段落</p>" console.log(div.textContent); // "<p>我是一个段落</p>" div.textContent = '<p>我是一个段落</p>'; console.log(div.innerHTML); // "<p>我是一个段落</p>" console.log(div.innerText); // "<p>我是一个段落</p>" console.log(div.textContent); // "<p>我是一个段落</p>" </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> <input type="text" id="input" value="1234"/> <div id="div">1234</div> <script> let div = document.getElementById('div'); console.log(div.innerHTML); // "1234" console.log(div.innerText); // "1234" console.log(div.textContent); // "1234" console.log(div.value); // undefined let input = document.getElementById('input'); console.log(input.innerHTML); // "" console.log(input.innerText); // "" console.log(input.textContent); // "" console.log(input.value); // "1234" </script> </body> </html>
更新样式
书写:变量名.style.csss属性名 = 'css属性值';
(csss属性名使用驼峰命名法)
<body>
<div id="div">1234</div>
<script>
let div = document.getElementById('div');
div.style.fontSize = '50px';
</script>
</body>
更新属性
element.setAttribute(attributename,attributevalue)
DOM 支持使用 getAttribute()
、setAttribute()
和removeAttribute()
方法读写删除自定义属性
setAttribute()
方法创建或改变某个新属性。如果指定属性已经存在,则只设置该值。
<body>
<a href="https://www.runoob.com" id="a">菜鸟教程</a>
<script>
let a = document.getElementById('a');
console.log(a.getAttribute);
a.setAttribute('href','https://www.baidu.com');
a.innerText = '百度';
</script>
</body>
element.attributename
只能设置元素本身具有的属性
<body>
<a href="https://www.runoob.com" id="a">菜鸟教程</a>
<script>
let a = document.getElementById('a');
console.log(a.href);
a.href = 'https://www.baidu.com';
a.innerText = '百度';
a.className = 'a';
</script>
</body>
更新结点
element.replaceChild(newNode,oldNode);
<body>
<div id="div">
<p id="p">我是一个段落</p>
</div>
<script>
let div = document.getElementById('div');
let p = document.getElementById('p');
let a = document.createElement('a');
div.replaceChild(a,p);
a.setAttribute('href','https://www.baidu.com');
a.innerText = '百度';
</script>
</body>
插入DOM结点
如果这个DOM节点是空的,例如,<div></div>
,那么,直接使用innerHTML = '<span>child</span>'
就可以修改DOM节点的内容,相当于“插入”了新的DOM节点。
如果这个DOM节点不是空的,那就不能这么做,因为innerHTML
会直接替换掉原来的所有子节点。
插入已有结点
因为我们插入的js
节点已经存在于当前的文档树,因此这个节点首先会从原先的位置删除,再插入到新的位置。
--------->
<p id="js">JavaScript</p>
<div id="list">
<p id="java">Java</p>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
</div>
<script>
let js = document.getElementById('js'),
let list = document.getElementById('list');
list.appendChild(js);
</script>
插入新建结点
--------->
<p id="js">JavaScript</p>
<div id="list">
<p id="java">Java</p>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
</div>
<script>
let list = document.getElementById('list');
let c = document.createElement('p');
c.id = 'c';
c.innerText = 'C';
list.appendChild(c);
</script>
insertBefore
把子节点插入到指定的位置。使用parentElement.insertBefore(newElement, referenceElement);
,子节点会插入到referenceElement
之前。
--------->
<div id="list">
<p id="java">Java</p>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
</div>
<script>
let list = document.getElementById('list');
let ref = document.getElementById('python');
let c = document.createElement('p');
c.id = 'c';
c.innerText = 'C';
list.insertBefore(c, ref);
</script>
删除DOM结点
要删除一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的removeChild
把自己删掉。
let self = document.getElementById('to-be-removed'); // // 拿到待删除节点
let parent = self.parentElement; // 拿到父节点
let removed = parent.removeChild(self); // 删除
removed === self; // true
<div id="parent">
<p>First</p>
<p>Second</p>
</div>
<script>
let parent = document.getElementById('parent');
parent.removeChild(parent.children[0]);
// 当<p>First</p>节点被删除后,parent.children的节点数量已经从2变为了1,索引[1]已经不存在了
parent.removeChild(parent.children[1]); // <-- 浏览器报错,
</script>