JavaScript基础

74 阅读7分钟

1.概述

1.相关概念

js:运行在客户端的脚本语言。

脚本语言:解释性语言,不需要编译,运行过程中直接由js解释器(js引擎)逐行来进行解释执行。

浏览器执行js的过程: 浏览器分为两个部分:渲染引擎+js引擎

  • 渲染引擎:解析HTML和CSS,俗称内核,如Chrome的blink
  • js引擎:又称js解释器。用来读取网页中的js代码,对其处理后运行,比如Chrome的V8

浏览器通过内置的js解释器来执行js代码。js引擎执行代码时逐行解释每一句源码(转换为机器语言),然后交由计算机执行。

js组成:

  • ECMAscript:js语法
  • DOM:页面文档对象模型
  • BOM:浏览器对象模型

ECMAScript: 是一种由Ecma国际(前身为欧洲计算机制造商协会,European Computer Manufacturers Association)通过ECMA-262标准化的脚本程序设计语言。这种语言在万维网上应用广泛,它往往被称为JavaScript(网景公司)或JScript(微软公司),所以它可以理解为是JavaScript的一个标准,但实际上后两者是ECMA-262标准的实现和扩展。

DOM: 文档对象模型,是 HTML 和 XML 文档的编程接口。

  • HTML DOM 定义了访问和操作 HTML 文档的标准方法。
  • DOM 以树结构表达 HTML 文档。

BOM: 浏览器对象模型,浏览器对象模型提供了独立与内容的、可以与浏览器窗口进行互动的对象结构,BOM由多个对象构成,其中代表浏览器窗口的window对象是BOM的顶层对象,其他对象都是该对象的子对象。


标识符: 开发人员为变量、属性、函数、参数取的名字。标识符不能是关键字或保留字。

关键字: js本身已经使用了的字。

保留字: 预留的关键字。

2.书写位置

HTMLmeta常规属性设置

js有三种书写位置:行内、内嵌、外部。

<body>
    <!--行内式的js,直接写到元素的内部-->
    <input type="button" value="按钮" onclick="alert('我被行内式点了')">
</body>
<head>
    <meta charset="UTF-8">
    <title>js1</title>
    <!--内嵌式的js-->
    <script>
        alert('内嵌式弹窗');
    </script>
</head>

my.js:

alert('外部式弹窗');

html:

    <script src="my.js"></script>

小结:

  • 可以将单行或少量js代码写在HTML标签的事件属性中(以on开头的属性,如onclick
  • 在HTML中推荐使用 "",在js中推荐使用 ''
  • 行内式可读性差,引号易错

2.输入输出语句

alert(msg) 浏览器弹出警示框

sonsole.log(msg) 浏览器控制台打印输出信息(F12)

prompt(info) 浏览器弹出输入框,用户可以输入

2.变量

变量:内存中开辟的存储数据的空间,数据可修改。可以通过变量名找到内存中的数据。

1.声明变量

var

        var age;
        age = 3;
        var name = 'zhangsan';

        var a = a,
            b = b,
            c = c;

使用没被赋值的变量——undefined

不声明,直接使用——不建议

重复声明同一变量并赋值——覆盖

    <script>
        var name = prompt('输入名字')
        alert(name);
    </script>

交换两个变量的值:

var temp = 0;
var a1 = 1;
var a2 = 2;

temp = a1;
a1 = a2;
a2 = temp;

console.log(a1,a2);

js声明变量的四种方式

2.数据类型

1.简单数据类型

不同数据的存储空间不同,为节省空间所以要分类。

  • js是一种弱类型(动态语言),即不用提前声明变量类型,在运行过程中,类型会被自动确定。
  • 运行时,js引擎根据 = 右边变量值来确认数据类型。
  • js是动态类型,意味着同一变量可作不同的类型。

简单数据类型:

简单数据类型说明默认值
Number数字型,包含 整型 浮点型0
Boolean布尔型false
String字符串""
Undefined只声明不赋值undefined
Null空值null
/*
/*
    数字型——Number
        Infinity——无穷大(越界)
        -Infinity——无穷小(越界)
        NaN——非数字
        isNaN——判断是否是Number,是返回true,否返回false
 */
var num = 1;
var PI = 3.14;
var num1 = 0o11;//八进制 9
var num2 = 0x11;//八进制 17

var max = Number.MAX_VALUE;//1.7976931348623157e+308
var min = Number.MIN_VALUE;//5e-324

console.log(isNaN(max));

/*
    字符串——String
        js可以单引号嵌双引号或者双引号嵌单引号
 */

var str1 = "我是\n'张三'呀";
var str2 = '"张三"是我呀';

var len = str1.length;//获取长度
var str3 = str1 + str2;//字符串拼接,拼接都会转为String
console.log(str1 + ' 有' + len + '个字符');


/*
    布尔型——Boolean
 */
var flag = true;
var num3 = flag + 1;//2

/*
    未定义——Undefined
 */
var und;
console.log(und);

/*
    非数字——NaN
 */
console.log(und + 1);

/*
    空值——Null
 */
console.log(null + 1);
console.log(null + '1');

console.log(typeof und);

字符串转义字符: 转义字符得写到引号中

转义符说明
\n换行,newLine
\\斜杠\
\'单引号
\"双引号
\ttab缩进
\b空格blank

获取数据类型——typeOf prompt获取到的值是字符型的

字面量: 源代码中一个固定值的表示法,通俗来说就是字面量表示如何表达这个值。

2数据类型的转换

把一种数据类型转换为另一种数据类型。

转换为字符串类型:

方法说明
toString()转换为字符串
String()强制转换转换成字符串
+拼接隐式转换
var num = 1;
var str = num.toString();
var str1 = String(num);
var str2 = num + '';

转换为数字类型:

方法说明
parseInt(String)将String转换为Number
parseFloat(String)将String转换为Number
Number()强制转换
- * /算术符隐式转换

转换为布尔型:

方法说明
Boolean()强转
/*
* 空值、否定的值会被转换为false,如:''、0、NaN、null、undefined
* 其余值转换为true
* */
console.log(Boolean(NaN));

3.运算符

运算符优先级:

优先级运算符顺序
1小括号()
2一元运算符++ -- !
3算术运算符先 * / 后 + -
4关系运算符> >= < <=
5相等运算符== != === !==
6逻辑运算符先&& 后||
7赋值运算符=
8逗号运算符,

注意——===== 的区别: == 代表相同, ===代表严格相同
== 如果两个值类型相同,再进行三个等号(===)的比较
如果两个值类型不同,也有可能相等,需根据以下规则进行类型转换在比较:

  • 如果一个是null,一个是undefined,那么相等
  • 如果一个是字符串,一个是数值,把字符串转换成数值之后再进行比较


===

  • 如果类型不同,就一定不相等
  • 如果两个都是数值,并且是同一个值,那么相等;如果其中至少一个是NaN,那么不相等。(判断一个值是否是NaN,只能使用isNaN( ) 来判断)
  • 如果两个都是字符串,每个位置的字符都一样,那么相等,否则不相等。
  • 如果两个值都是true,或是false,那么相等
  • 如果两个值都引用同一个对象或是函数,那么相等,否则不相等
  • 如果两个值都是null,或是undefined,那么相等

4.if、switch、for、while

1.if

var age = prompt('输入年龄') - 0;
if (age >= 18){
    alert("已成年");
}else {
    alert('未成年');
}

2.三元表达式

var num = 17;
console.log(num % 10 == 7 ? '对' : '不对');

3.switch

switch (prompt('输入你的姓氏')) {
    case '陈':
        alert('你姓陈');
        break;
    case '刘':
        alert('你姓刘');
        break;
    case '吕':
        alert('你姓吕');
        break;
    case '董':
        alert('你姓董');
        break;
    default:
        alert('你姓宋');
}

4.for

for (var i = 0; i < 100; i++) {
    console.log(i);
}

打印金字塔⭐

var str = '';
for (var i = 1, j = 5; i <= 5; i++,j--) {
    var m = j, n = i;
    while (m >= 0){
        str += ' ';
        m--;
    }
    while (n > 0){
        str += '⭐';
        n --;
    }
    str += '\n';
}
console.log(str)

5.while

var i = 100;
while (i > 1){
    console.log(i);
    i -= 10;
}

6.continue和break

continue 跳出本次循环

break 跳出一层循环

var i = 100;

OUT:
for (var j = 0; j < 100; j++) {
    for (var k = 0; k < 100; k++) {
        if (i - 10 == 0) break OUT;
        console.log(i);
        i--;
    }
}

5.数组

一组数据的集合。

创建数组:

var a = [];  //空数组
a[0]=1;
a[1]="hello";

//数组下标不仅仅可以是数字,也可以为文本字符串,那么此时数组就是一个关联数组
a["姓名"]="张三";
a["年龄"]=23;

var a = [1, 2, 3];  //包含具体元素的数组

var a = new Array();  //空数组

var a = new Array(1,2,3);//数值

var a = new Array(3);//长度

修改数组长度:

var a = new Array(1,2,3);//数值
a.length = 5;
console.log(a);

检测是否为数组:

/*
    instanceof运算符
 */
var arr = [];
console.log(arr instanceof  Array);
/*
    Array.isArray()
 */
console.log(Array.isArray(arr));

往数组中增删元素:

/*
    push: 末尾追加元素,返回值为新数组长度
 */
var arr = [1,2,3,4];
arr.push(8,7,6);
/*
    unshift: 开头添加元素,返回值为新数组的长度
 */
arr.unshift(9,4);
/*
    pop: 删除数组最后一个元素,并返回删除的元素
 */
arr.pop();
/*
    shift: 删除数组第一个元素,并返回删除的元素
 */
arr.shift();

翻转数组

reverse、sort、indexOf、lastIndexOf、toString、join

6.函数

将重复使用的代码封装成函数。

function f() {
    console.log('f');
    return undefined;
}
f();
function add(num) {
    var sum = 0;
    while (num > 0){
        sum += num;
        num--;
    }
    return sum;
}

var sum = add(100);
var add = function(num) {
    var sum = 0;
    while (num > 0){
        sum += num;
        num--;
    }
    return sum;
}

console.log(add(100))

函数形参与实参个数不匹配的问题:

  • 实参个数 > 形参个数 —— 取到形参的个数,多余的实参无效
  • 实参个数 < 形参个数 —— 多余的形参接收不到值,为undefined

函数的返回值: 如果需要返回值,就返回;如果不需要返回值,仍然建议返回一个undefined。

arguments 是当前函数的一个内置对象,所有函数都有一个arguments对象,其中存储了传递的所有实参(数组形式)。 可以获取并修改对应的形参值。

function func1(a, b, c) {
  console.log(arguments[0]);
  // expected output: 1

  console.log(arguments[1]);
  // expected output: 2

  console.log(arguments[2]);
  // expected output: 3
}

func1(1, 2, 3);

JavaScript的作用域: 代码名在某个范围内起作用和效果,目的是为了提高程序的可靠性且减少命名冲突。

js的作用域(es6)之前: 全局作用域、局部作用域

  • 全局:整个script标签、一个单独的js文件
  • 局部:在函数内部

js在es6时才新增的块级作用域。

7.预解析

js代码是由浏览器的js解析器来执行的。js解析器运行js代码的时候分为两步:预解析、代码执行。

  • 预解析:js引擎将js里面的所有var还有function提升到当前作用域的最前面
  • 代码执行:执行代码书写的顺序,从上往下执行

预解析: 分为 变量与解析(函数提升) 和 函数与解析(变量提升)。

  • 变量提升:把所有的变量声明提升到当前的作用域最前面,不提升赋值操作
  • 函数提升:把所有的函数声明提升到当前作用域的最前面,不调用函数

8.对象

对象是一个具体的事物。

在js中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。

对象由属性和方法组成的。

  • 属性:事务的特征(如一个人的发色)
  • 方法:事务的行为(如学习)

相比于变量和数组,对象的表达结构更清晰、更强大。

创建对象的三种方式:

  • 字面量
  • new Object
  • 构造函数
/*
	通过Object()方法来创建
*/
var obj2 = new Object();

/*
	通过字面量法创建对象
*/
var obj = {};//空对象
obj.name = 'zhangsan';
obj.behave = function(){
	console.log('无所事事');
}

var obj1 = {
    oname: '张三',
    age: 18,
    sex: '男',
    behave: function () {
        console.log('法律讲坛');
    }
}
console.log(obj1.oname);
console.log(obj1['age']);
obj1.behave();

/*
	通过构造函数创建对象
		提高代码复用性,减少重复代码
		函数中封装的是对象(类似Java的类)
*/
function Animal(uname,species) {
    this.uname = uname;
    this.species = species;
    this.roar = function (call) {
        console.log(uname + ': ' + call);
    }
}

var cat = new Animal('胖橘','cat');
cat.roar('meow');
console.log(typeof cat);

new 的执行过程:

  • new 构造函数 在内存中创建了一个空的对象
  • this 会指向这个空的对象
  • 执行构造函数中的代码,给空对象添加属性和方法
  • 返回这个对象

for in遍历对象: 将属性和方法一起遍历。

for (const catKey in cat) {
    console.log(catKey);//catKey变量 输出 属性名
    console.log(cat[catKey]);//得到属性值,arguments内置对象
}

9.内置对象

js中的对象分为3种:自定义对象、内置对象、浏览器对象。

前面两种对象是js基础内容,属于ECMAScript,第三个属于js独有的。

内置对象就是js自带的一些对象,这些对象供开发者调用,并提供了一些常用的或最基本而必要的功能(属性和方法)。

MDN: developer.mozilla.org/zh-CN/

W3C: www.w3school.com.cn/

自定义数学对象:

var myMath = {
        max: function(){
        var max = arguments[0];
        for (var i = 1; i < arguments.length; i++) {
            if (arguments[i] > max){
                max = arguments[i];
            }
        }
        return max;
    }
}

console.log(myMath.max(1,5,98,75));

Math对象

Date对象

获取当前距离1970年1月1日00:00的毫秒数(时间戳):

var date = new Date();
/*
    方法一
 */
console.log(date.valueOf());
/*
    方法二
 */
console.log(date.getTime());
/*
    方法三
 */
console.log(+new Date());
/*
    方法四
 */
console.log(Date.now());

倒计时:

function countDown(time) {
    var nowTime = +new Date();//时间戳

    var inputTime = +new Date(time) ;//输入时间的时间戳

    var times = (inputTime - nowTime) / 1000;//差值

    var d = parseInt(times / 60 / 60 /24);//天
    d = d < 10 ? '0' + d : d;
    var h = parseInt(times / 60 / 60 % 24);//时
    h = h < 10 ? '0' + h : h;
    var m = parseInt(times / 60 % 60)//分
    m = m < 10 ? '0' + m : m;
    var s = parseInt(times % 60);
    return d + '天' + h + '时' + m + '分' + s + '秒';
}

console.log(countDown('2022-6-3 11:0:00'));
var date = new Date();
console.log(date);

10字符串对象

基本包装类型: 将简单数据类型包装为复杂数据类型,这样基本数据类型就有了属性和方法。

包装步骤:

var str = 'Tom';

1.将简单数据类型包装为复杂数据类型

var temp = new String('Tom');

2.把临时变量的值给 str

str = temp;

3.销毁临时变量

temp = null;

字符串不可变: 字符串中的值不可变,如果重复给一个字符串变量赋值,会不断在内存中开辟空间来存储新值,然后让字符串变量指向新值。

indexOf(value) 获取字符在字符串中的位置 charAt(index) 获取指定位置的字符 charCodeAt(index) 获取指定位置的字符的ascll码 str[index] 获取指定位置处的值

统计字符串中每个字符出现的次数:

var strs = 'jcsdibvdsovsjnjk';

function getNums(strs){
    var nums = {};
    for (var i = 0; i < strs.length; i++){
        var str = strs.charAt(i);
        if (nums[str]){
            nums[str]++;
        }else {
            nums[str] = 1;
        }
    }
    console.log(nums);
}
getNums(strs);

获取出现次数最多的字符:

var strs = 'jcsdibvdsovsjnjk';

function getNums(strs){
    var nums = {};
    for (var i = 0; i < strs.length; i++){
        var str = strs.charAt(i);
        if (nums[str]){
            nums[str]++;
        }else {
            nums[str] = 1;
        }
    }
    console.log(nums);
    //遍历对象
    var max = 0;
    var target;
    for (var k in nums){
        if (nums[k] > max){
            max = nums[k];
            target = k;
        }
    }
    console.log('出现次数最多字符的是 ' + target + ',出现了' + max + '次');
}
getNums(strs);

concat(str1,str2,...) 等效于+ substr(start,end) 截取子串 replace(oldStr,newStr) 替换字符串 split(‘*’) 分隔符 toUpperCase() 全转换为大写 toLowerCase() 全转换为小写

11数据类型内存分配

js分为两种数据类型:简单数据类型(值类型)、复杂数据类型(引用类型)

  • 值类型:在存储时变量中存储的是值本身
    String、Number、Boolean、undefined、null(返回的是一个空对象)
  • 引用类型:用 new 创建的对象(自定义对象、系统对象)
    Object、Array、Date

堆和栈:

  • 堆(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等
    存放简单数据类型
  • 栈(操作系统):由程序员分配释放,如果不释放,则由垃圾回收机制回收
    存储复杂数据类型

JavaScript系列之内存分配 - 知乎 (zhihu.com)