观此文,你仍需有C语言、HTML、CSS基础之基础。
本文规范基本上基于ECMAScript2015(就是ES6)。
你需要认识C语言的分支与循环处理、HTML的常见标签以及CSS的基础选择器。如果你对C语言的函数指针或者函数式编程常用的lambda表达式有所理解的话,将有助你快速上手JavaScript。
(事件那边你要是懂一点WPF的event原理就更好了……不过没人学C#吧……
如何输出
console.log(); //输出信息
console.warn(); //输出警告,是黄色的
console.error(); //输出报错,是红色的(虽然也不会导致程序中止
它们可以通过传入多个参数来实现一次性输出更多数据。
数据类型
通过let声明/定义变量,通过const声明常量。(不再推荐使用var)
例如:
const name = 'Alfred'; //name是常量,必须直接初始化,之后不可变
let age = 19; //age是变量,仍可变
你可与使用typeof运算符来输出一个量的数据类型,例如:
console.log(typeof age); //向控制台输出age的类型(输出number)
string
用单引号或者双引号包围的字符串。
例子中我们有:
const s = 'Hello World';
连接
使用加号可以连接字符串。
可以使用模板字符串来往字符串里面填入数据(使用反引号)。
例如:
let info1 = 'My name is ' + name + ', and I am ' + age + ' years old.'; //使用加法连接
let info2 = `My name is ${name}, and I am ${age} years old.`; //使用模板字符串
//info1 和 info2 两个字符串的内容一致
获取长度
使用字符串的length
属性获取字符串长度。
例如:
console.log(s.length); //向控制台输出字符串s的长度(输出11)
转变字符
使用字符串的toUpperCase()
方法把字符串里的字母都转成大写,使用toLowerCase()
方法把字符串里的字母都转成小写。注意,返回值才是所求的字符串,原字符串并不会改变。
例如:
console.log(s.toUpperCase()); //向控制台输出全为大写字母的字符串s(输出为HELLO WORLD)
console.log(s.toLowerCase()); //向控制台输出全为小写字母的字符串s(输出为hello world)
获取子字符串
使用字符串的substring()
方法获取字符串的子串。该方法有两个参数,第一个参数代表子串从原字符串的第几个开始(下标从0开始),第二个参数代表子串在父串的第几个字符前结束。注意,第一个参数所指的字符会被包含在子串中而第二个参数所指的不会。
例如:
console.log(s.substring(2,5));
//向控制台输出s的自下标为2的字符开始,自下标为5的字符结束的子串(输出为llo)
将字符串分割到数组中
使用字符串的split()
方法将字符串分割到数组中。该方法有一个参数,为分割的分隔符,此方法将按此分隔符分割该字符串到数组。如果要分割每个字符,请使用参数''
(空字符串)。注意,参数将不出现在分割完的字符串中。
例如:
console.log(s.split(''));
//输出["H", "e", "l", "l", "o", " ", "W", "o", "r", "l", "d"]
console.log(s.split(' '));
//输出["Hello", "World"]
console.log(s.split('ell'));
//输出["H", "o World"]
object
数组
一个数组内可以有多个数据,这些数据可以是不同类型的。
数组下标从0开始,逐项递增。
即使数组被定义为const,但仍可改变数组,只是不能给该量赋值其他数组。
创建数组
有多种方法创建数组:
const array1 = new Array(1, 2); //使用构造函数创建,括号内可以传入一些值以初始化数组(也可以不传)
const array2 = [1, 2, '233']; //直接创建
访问数组元素
直接使用[]
即可。
console.log(array1[0]); //向控制台输出array1数组的第一项(下标为0)(输出1)
给数组添加元素
虽然array1只有两个元素,但是要想给它加元素,直接array1[2] = 3
即可。注意,如果添加的位置比较不和原来的贴在一起,中间会用empty填充。
array1[2] = 3;
console.log(array1); //输出[1, 2, 3],长度为3
array1[6] = 7;
console.log(array1); //输出[1, 2, 3, empty × 3, 7],长度为7(empty也算长度)
//特殊情况:
const arr = [1, 2];
arr[-2] = 5;
console.log(arr); //输出 [1, 2, -2: 5],长度为2
//要访问下标为-2的元素,可以使用arr[-2]或者arr['-2']
向末尾追加,可以使用数组的push()
方法,例如:
array2.push(666);
console.log(array2); //输出[1, 2, '233', 666]
向开头添加,可以使用数组的unshift()
方法,例如:
array2.unshift(9);
console.log(array2); //输出[9, 1, 2, '233', 666]
去除数组中的元素
使用数组的pop()
方法,可以去除数组的最后一个元素,同时,此方法会返回被去除的元素。(类似于其他语音的pushBack()
方法。)例如:
let x = array2.pop();
console.log(array2); //输出[9, 1, 2, '233']
console.log(x); //输出666
检查某个量是不是数组
使用Array.isArray()
方法可以检查一个量是不是数组,如果传入的参数是数组,它会返回true;否则,它会返回false。
获取数组中某个值的下标
使用数组的indexOf()
方法可以获取数组中该元素(由参数传入)的下标。如果参数内容不存在于数组中,该函数会返回-1
。例如:
console.log(array2.indexOf(2)); //输出2
console.log(array2.indexOf(999)); //输出-1
遍历数组
可以通过for...of
循环遍历数组的值,例如:
for(let x of array2) {
console.log(x);
}
//控制台会依次输出9, 1, 2, 233
或者使用数组的forEach()
方法进行遍历。该方法需要传入一个参数作为回调函数,该回调函数有一个参数,即为每次遍历时代表的数组的内容,每次遍历执行一次回调函数。例如:
array2.forEach(function(x) { console.log(x); }); //参数为回调匿名函数
array2.forEach(x => console.log(x) ); //使用λ表达式的匿名函数
//控制台会依次输出9, 1, 2, 233
取出数组中对象的特定属性值并生成新数组
可以通过数组的map()
方法实现。该方法需要传入一个参数作为回调函数,该回调函数有一个参数,即为每次遍历时代表的数组的内容,每次遍历执行一次回调函数,该回调函数需要返回特定的属性值。此方法的返回值为所求的数组。例如:
//获取数组中所有对象的id
const x = [
{
id: 1,
name: 'Alfred'
},
{
id: 2,
name: 'John'
}
]
const ids = x.map(function(i) { return i.id; });
const ids = x.map(i => i.id); //λ表达式版
console.log(ids);
//控制台会输出[1, 2]
筛选数组中满足特定属性值要求的对象并生成新对象数组
可以通过数组的filter()
方法实现。该方法需要传入一个参数作为回调函数,该回调函数有一个参数,即为每次遍历时代表的数组的内容,每次遍历执行一次回调函数,该回调函数需要返回一个布尔值,为真的情况下此对象会被加入新数组。此方法的返回值为所求的数组。例如:
//筛选所有id=2的对象
const x = [
{
id: 1,
name: 'Alfred'
},
{
id: 2,
name: 'John'
}
]
const id2 = x.filter(function(i) { return i.id === 2; });
const id2 = x.filter(i => i.id === 2); //λ表达式版
console.log(id2);
//控制台会输出[{id: 2, name: "John"}]
对象
对象实际上就是大括号包围的键值对。({key: value}
)
即使对象被定义为const,但仍可改变对象的内容,只是不能给该量赋值其他对象。
例子中,有:
const person = {
name: 'Alfred',
age: 19,
address: {
province: 'Zhejiang',
city: 'Hangzhou'
}
};
访问对象的单个值
使用.
运算符来方位对象的单个值。例如:
console.log(person.age); //输出19
解构对象
可以通过解构对象的方式从对象中取出一定数量的值。例如:
const { name, age, address: {city} } = person; //现在有3个const量分别为name、age和city
添加属性
可以直接为对象添加新的键值对,例如:
person.email = '[email protected]';
//那么person现在是
/*
{
name: 'Alfred',
age: 19,
address: {
province: 'Zhejiang',
city: 'Hangzhou' },
email: '[email protected]'
}
*/
遍历对象的属性
可以通过for...in
循环遍历对象的属性,例如:
for (x in person) {
console.log(x);
}
//遍历属性的名字(键),控制台会依次输出name, age, address, email
for (x in person){
console.log(person[x]);
}
//遍历属性的值,控制台会依次输出Alfred, 19, {province: "Zhejiang", city: "Hangzhou"}, [email protected]
JSON
JSON是一种数据格式,长得很像JavaScript的对象,经常用于传输数据。
使用JSON.stringify()
函数可以把JavaScript的object类型数据转换为JSON字符串。例如:
const a = JSON.stringify(person);
console.log(a);
/*输出
{ "name":"Alfred",
"age":19,
"address":{"province":"Zhejiang","city":"Hangzhou"},
"email":"[email protected]"
}
*/
其他
如果你给一个变量赋值为null
,那么你用typeof
运算符查看这个量的类型的时候,会发现它是object
类型。
只定义了而未初始化的变量,它的默认值是undefined
。
其他待补充。
DOM
如何选择元素
使用document.querySelector()
和document.querySelectorAll()
来选择HTML上的标签。
前者用来选择单个元素,后者可以选择多个元素并将其组入一个NodeList
,它类似于数组,可以进行数组的一些操作(比如forEach()
遍历和NodeList.children[]
来选择第几个元素)。这两个函数的参数是一个字符串,字符串是选择器,形式同CSS的标签选择器、class选择器(加.
)和id选择器(加#
),例如:
const elem1 = document.querySelector('#id'); //如果实际可选的元素不止一个,则选择第一个
const elem2 = document.querySelectorAll('.item'); //选中了所有.item标记的元素
删除页面元素
可以使用页面元素.remove()
方法完成。
elem1.remove(); //移除页面上的以#id标记的元素
elem2.remove(); //移除页面上的所有的.item标记的元素
elem2.lastElementChild.remove(); //移除elem2组合中的最后一个元素
添加页面元素
可以通过document.createElement()
方法来创建一个元素。此方法的参数为你要创建的元素的标签名,它的返回值为新创建好的元素DOM对象。要往元素内添加元素,可以使用元素的appendChild()
方法,参数为你要插入的元素。特殊地,若要插入文字,参数可以设置为document.createTextNode()
,此方法的参数为元素内的字符串。例如:
//在一个ul内插入一个li,li的内容为2333
const ul = document.querySelector('ul') //选中ul
const li = document.createElement('li'); //创建li
li.appendChild(document.createTextNode('2333')); //li内插入字符
ul.appendChild(li); //把li加入ul
获取与编辑页面元素的内容试试
使用元素对象的textContent
、innerText
、innerHTML
属性可以方便的获取或者更改元素的内容。
elem2.firstElementChild.textContent = 'Hello'; //修改elem2集合中的第一个元素的标签中的文本内容
elem2.firstElementChild.innerText = 'Hello'; //效果同上
elem1.innerHTML = '<a href="xxx">233</a>'; //修改elem1的内嵌html代码
console.log(document.querySelector('h1').textContent); //输出的是文本
console.log(document.querySelector('h1').innerText); //同上
console.log(document.querySelector('h1').innerHTML); //输出的是该元素的内嵌的所有HTML代码与文本
输入框里面的内容,可以通过元素对象的value
属性来获取。
获取与编辑页面元素的HTML属性与CSS样式
直接使用元素对象的相应属性并赋值即可。
给HTML元素添加新类使用元素的classList.add()
方法实现,该函数接受一个字符串参数,即为要添加的class名;另外有一个方法叫classList.remove()
,可以去除元素的某个class。
elem1.style.background = 'red'; //把elem1元素的背景改成红色的(CSS)
elem1.href = 'https://www.baidu.com'; //把elem的href属性设为百度(之前没设置的会新指定)
console.log(elem1.target); //输出elem1元素的target属性的内容
elem1.classList.add('container'); //给elem1的class属性添加一个 container 类(可用于CSS选择)
事件
以一个按钮元素为例。
btn = document.querySelector('.btn');
为一个元素添加监听事件
使用元素的addEventListener()
方法可以为特定的元素添加监听事件。该函数有两个参数,第一个参数是一个字符串,代表要监听的事件;第二个参数为在目标元素上监听到该事件时所触发的回调函数。关于这个回调函数,它接受一个参数,这个参数是被监听方法自动传入的事件对象,函数体即该事件触发时执行的行为。该事件对象的target
属性即为触发本事件的元素本身。例如,我给这个按钮添加单击按下时的监听事件:
btn.addEventListener('click', e => {
e.preventDefault(); //阻止该行为的默认事件,比如提交表单、跳转网页等
console.log('clicked!');
});
常用事件有:
- click:单击
- mouseover:鼠标移入、悬浮在上
- mouseout:鼠标移出
- submit:表单提交
以及其他的比如输入事件等等。
事件可以用于检查表单格式(我懒得举例子了,建议自己实现一下,获取DOM对象然后在函数体内确认)。
Ending
看到这里就把整个文章看完了,但是你以为你这就可以愉快的写js了吗?
并不!
你要是还想了解更多的JavaScript语言方面的东西,推荐你几本书:《ES6标准入门(第三版)》、《JavaScript高级程序设计(第四版)》和《JavaScript DOM编程艺术》。
Good luck, and good night!