JavaScrip基础知识
时间:2022-10-12 17:30:00
一、什么是JavaScript?
JavaScript
:它是一种轻量级、解释性或即时编译的编程语言,具有函数优先级。它是一种弱型脚本语言,其源代码在客户端运行前不需要编译,而是由浏览器解释。
在前端中:
html
它主要用于决定网页的结构,即网页架构层
。
css
主要用于美化网页,是网页表现层
。
JavaScript
主要用于与网页动态交互,是网页行为层
。
DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>JavaScript学习title> <script type="text/javascript"> alert("hello world"); script> head> <body> body> html>
js标签上写着代码script
中,其中type
属性不能写,默认是javascript。script
可以写标签body
也可以写在标签下head
还可以从外部引入标签,html文件如下:
DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">
<title
>JavaScript学习title>
<script src="studyJS.js">script>
head>
<body>
body>
html>
注意:script
标签必须成对出现,不能自闭合,不然会出现错误。
js文件如下,文件名为studyJS.js
:
alert("hello world");
alter()
是js中经常用到的方法,意思是提醒,它会在浏览器页面弹出一个信息框,给用户一些提示信息。
二、基本语法入门
(1)var和let
js的语法和代码规范和java
基本一样。所以我们可以很容易地学会js的语法。声明变量如下:
var number = 1;
number=2;
alert(number);
值得注意的是:js中所有的变量类型都是var
,在ES6
中,新增了let
,也可以用来声明变量。
var
和let
有以下的区别:
(1)var是函数作用域
,let是块作用域
。在函数中声明了var,整个函数内都是有效的,比如说在for循环内定义的一个var变量,实际上其在for循环以外也是可以访问的。而let由于是块作用域,所以如果在块作用域内定义的变量,比如说在for循环内,在其外面是不可被访问的,所以for循环推荐用let。
(2)let不能被重新定义,但是var可以。
(3)let不能在定义之前访问该变量,但是var可以。let必须先声明,再使用。而var先使用后声明也行,只不过直接使用但没有定义的时候,其值是undefined
。var有一个变量提升的过程,当整个函数作用域被创建的时候,实际上var定义的变量都会被创建,并且如果此时没有初始化的话,则默认为初始化一个undefined
。
(2)数据类型
(1)number
数值类型。在js中,不区分整数和浮点数,无论是整数还是浮点数,它们的类型都是number
。
let number = 1; //整数
number=1.2; //浮点数
number=1.2e4; //科学计数法
number=NaN; //不是一个数字
number=Infinity; //无穷大的数字
有两个值得注意的是NaN
和Infinity
。前者表示的是不是一个数字,即Not a Numbe
,后者表示无穷大。
(2)null和undefined
:前者表示空,后者表示未定义。
(3)数组类型
:js的数组中可以装任意类型的数据。
let a=[1,2,3,4,null,'2345',undefined];
有几点需要注意:
【1】数组的长度用length
来获得。
let a=[1,2,3,4,null,'2345',undefined];
let length = a.length; //7
【2】倘若数组越界了,如访问a[7]
,则会提示undefined
。
【3】如果给a.length
赋值,赋值超过原本的数组大小,数组就会扩大,后面加入进来的元素是空;如果赋值小于原本的数组大小,那么元素就会丢失。
【4】通过元素获得下标索引:
let index = a.indexOf(2); // 1
【5】通过函数slice()
截取一部分数组,跟字符串类型中的substring
一样。
let slice = a.slice(1, 5);
结果为[2, 3, 4, null]
。
【6】往数组尾部添加数据:push()
和pop()
。
a.push("牛马", "hello"); //添加数据,结果为:[1, 2, 3, 4, null, '2345', undefined, '牛马', 'hello']
a.pop(); //弹出尾部的一个元素,结果为:[1, 2, 3, 4, null, '2345', undefined, '牛马']
【7】往数组头部添加数据:unshift()
和shift()
。
a.unshift("赢了吗", "赢麻了"); //往头部加入数据,结果为:['赢了吗', '赢麻了', 1, 2, 3, 4, null, '2345', undefined, '牛马']
a.shift(); //弹出头部的一个数据,结果为:['赢麻了', 1, 2, 3, 4, null, '2345', undefined, '牛马']
【8】数组中的元素排序:sort()
。
let alp = ["a","b","j","i","e","y"];
alp.sort();
结果为:['a', 'b', 'e', 'i', 'j', 'y']
。
【9】数组中的元素反转:reverse()
。
alp.reverse();
结果为:['y', 'j', 'i', 'e', 'b', 'a']
,
【10】拼接数组:concat()
alp.concat([1,2,3])
结果为:['y', 'j', 'i', 'e', 'b', 'a', 1, 2, 3]
,需要注意的是:拼接数组并不会改变原来的数组,而是返回一个新的数组。
【11】打印拼接数组,使用特定的字符串连接,join()
:
let s = alp.join("-");
结果为:'y-j-i-e-b-a'
。
【12】遍历数组:
1.通过普通for循环
:
for (let i = 0; i < alp.length; i++) {
console.log(alp[i]);
}
2.通过for of
循环:
for (let string of alp) {
console.log(string);
}
3.通过forEach()
方法:
alp.forEach(function (s) {
console.log(s);
});
(4)对象类型
:对象定义如下所示,每个属性之间用,
隔开,最后一个属性可以不用。
let b={
name: "牛马",
age:23,
gender:"boy"
}
可以理解为若干个键值对,并且所有的键都是字符串,值可以是任意的对象。有几点需要注意:
【1】使用一个不存在的对象属性,不会报错。
【2】动态地删减属性,通过delete
删除对象的属性。
delete b.gender;
结果对象中还剩下:{name: '牛马', age: 23}
。
【3】动态的增加属性,直接给新的属性赋值即可。
b.address = "工地";
结果为:{name: '牛马', age: 23, address: '工地'}
。
【4】判断某个属性是否在这个对象中。
let b1 = 'name' in b;
结果为true
。
【5】判断一个属性是否是这个对象自身拥有的,可以用hasOwnProperty
函数。
b.hasOwnProperty('name');
结果为true
。
(5)字符串类型
:可以用单引号,也可以用双引号。
let c = "abc";
let d = 'efg';
需要注意的点:
【1】多行字符串的编写可以使用“飘”符号(
键盘上Table上面的那个键)
括起来,如下所示:
let e = ` 你好啊 中国 我是外星人 `
【2】模板字符串,以下代码输出为:纯纯牛马。
let name = "牛马";
let msg = `纯纯${
name}`;
console.log(msg);
【3】字符串长度:用函数length
即可求出。
let str = "1234545"
let len = str.length;
【4】js中的字符串是不可变的。
【5】大小写转换:
let str = "abcdf"
let toUp = str.toUpperCase();
let toLow = str.toLowerCase();
toUpperCase
:转大写。toLowerCase
:转小写。
【6】截取子字符串:
let str = "abcdf"
let subStr = str.substring(1, 3);
上面代码结果为:bc
,规则是前闭后开
,即[1,3)
。
(6)布尔类型
:true
和false
。
(3)运算符
(1)逻辑运算和java
中的一样,都可以分为&&
、||
、!
。
(2)比较运算符也和java
中的一样,只是要注意=
,==
,===
的区别。
==
:等于,类型不一样,值一样,也会判断为true
。
console.log(1 == "1"); //true
===
:绝对等于,类型一样,值一样,才会判断为true
。
console.log(1 === "1"); //false
console.log(1 === 1); //true
有几点需要注意:
(1)NaN===NaN
的结果为false
,说明NaN
与所有的数值都不相等,包括它本身。只能通过isNaN()
这个函数来判断某个数值类型是不是NaN
。
(2)尽量避免使用浮点数进行运算,因为存在精度问题!
console.log((1/3)===1-(2/3)); //false
(4)严格检查模式
js是一种比较随意的语言,所以有的时候可能会出错,因此我们可以在js代码前面加上一句代码'use strict'
,表示启用严格检查模式,防止因为JavaScript的随意性导致出现的一系列问题。并且这句代码要放在第一行才会起作用
(5)map和set
(1)map:存储键值对
let map = new Map([["jack", 100], ["tom", 90]]);
let number = map.get("jack"); //通过键获取值
map.set("牛马", 1000);
map.delete("牛马");
var b4 = map.has("jack"); //true
get()
方法是通过键获取值。set()
方法是增加新的键值对。delete()
方法是通过键删除这个键值对。has()
方法是判断某元素是否存在于集合中。其原理跟java中的map是类似的,不多赘述。
(2)set:存储无序不重复的元素
let set = new Set([1, 2, 1, 3, 3]); // {1, 2, 3}
set.add(5);
set.delete(1);
let b3 = set.has(3); //true
add()
方法是添加元素。delete()
方法是删除元素。has()
方法是判断某元素是否存在于集合中。
(6)iterator迭代器
通过for of
来遍历map和set即可:
for (let mapElement of map) {
console.log(mapElement);
}
for (let number1 of set) {
console.log(number1);
}
三、函数
(1)函数的定义
定义方式一
function abs(x){
if (x >= 0) {
return x;
} else {
return -x;
}
}
一旦执行到return
代表函数结束,返回结果。如果没有执行return
,函数也会返回结果,结果为:undefined
。
定义方式二
let abs = function (x) {
if (x >= 0) {
return x;
} else {
return -x;
}
};
function (x){.....}
这是一个匿名函数,但是可以把结果赋值给abs,所以可以通过abs来调用。
上面两种方式的效果是一样的。
(2)函数调用
函数调用
直接根据函数名调用即可:
abs(10);
abs(-10);
函数的参数问题
js的函数可以传任意个参数,也可以不传递参数。
假设不传递参数,或者传递的参数类型错误应该如何规避?对于这个问题,我们可以通过手动抛异常
来规避。
let abs = function (x) {
if (typeof x !== 'number') {
throw "Not A Number";
}
if (x >= 0) {
return x;
} else {
return -x;
}
};
typeof
意思是判断某个值是不是这个类型的函数。
假设传进来的参数存在多个?js中有个关键字是arguments
,代表传递进来的所有参数,这些参数组成一个数组。
let abs = function (x) {
if (typeof x !== 'number') {
throw "Not A Number";
}
for (let argument of arguments) {
console.log(argument); //x也包含在里面
}
if (x >= 0) {
return x;
} else {
return -x;
}
};
如何获取所有参数中除了真正的形参之外的所有参数呢?可以使用...(数组名)
的形式,类似于java中的可变参数。
let a = function (a, b, ...rest) {
//rest可以理解为数组名
console.log("a==>" + a);
console.log("b==>" + b);
console.log(rest);
};
执行效果如下:
a(123,4234,545,6)
a==>123
b==>4234
(2) [545, 6]
(3)变量的作用域
在js中, var
定义的变量实际上是有作用域的。
(1)假设变量在函数体中声明,则在函数体外不可以使用。
function a() {
var x=1;
x = x++;
}
console.log(x);
结果为:Uncaught ReferenceError: x is not defined
。
(2)内部函数可以访问外部函数的成员,反之则不行。
function a() {
var x=1;
function b(){
var y= x+1;
console.log(y);
}
var z = x+y;
}
a();
结果为:Uncaught ReferenceError: y is not defined
。
(3)内部函数和外部函数重名的情况:
function a() {
var x=1;
function b(){
var x = 'a'
console.log('inner===>' + x);
}
b();
console.log('outer===>' + x);
}
a();
输出为:
inner===>a
outer===>1
在js中,函数查找变量是从自身函数开始,从“内”到“外”。
(4)提升变量的作用域:
function a(){
var x = 'x' + y;
console.log(x);
var y = 'y';
}
a();
结果为:xundefined
。说明:js执行引擎自动提升了变量y的声明,但是没有提升变量y的赋值。
下面这段代码跟上面那段代码的作用是一样的:
function a(){
var y;
var x = 'x' + y;
console.log(x);
y = 'y';
}
a();
结果照样为:xundefined
。
(4)全局对象window
var x = 1; //全局变量
console.log(x);
console.log(window.x);
默认所有的全局变量,都会自动绑定到window
对象下。alter
函数本身也是window
的一个变量。
由于我们所有的全局变量都会绑定到我们的对象window
上,如果不同的js文件,使用了相同的全局变量,那么就会遇到冲突,这个时候该如何解决呢?
//定义全局唯一变量
var StudyJS = {
};
//定义全局变量
StudyJS.name = "牛马";
StudyJS.add = function(a,b){
return a+b;
}
说明:可以把自己的代码放入自己定义的唯一命名空间中,减少全局命名冲突的问题。
(5)方法
方法定义:
就是把函数放到对象的里面
,因为对象只有两样东西:属性和方法。
var student={
name: "牛马",
birth:2000,
age: function () {
var now = new Date().getFullYear();
return now - this.birth;
}
}
console.log(student.age());
结果为:22。
注意:调用方法一定要加括号。
ps
:js中调用函数加括号和不加括号的区别?
函数名其实就是指向函数的指针。
不加括号可以认为是查看函数的完整信息。
不加括号传参,相当于传入函整体。
加括号表示立即调用(执行)这个函数里面的代码。
thsi关键字
this
关键字跟java
中的语法一样,都是得到当前调用它的对象的属性值。将上面的代码拆开如下:
function getAge() {
var now = new Date().getFullYear();
return now - this.birth;
}
var student={
name: "牛马",
birth:2000,
age: getAge(),
}
console.log(student.age);
结果为:NaN
,因为此时的函数getAge
是属于window
对象的,而window
对象中并不存在birth
这个属性,所以返回这个结果。
apply
var apply = getAge.apply(student, []); //this指向student这个对象,参数为空
console.log(apply);
在js中每一个函数都有appy
这个方法,可以控制this
指针的指向。如上面的代码中结果为:22。
(6)Date对象
var date = new Date(元器件数据手册
、IC替代型号,打造电子元器件IC百科大全!