Web前端的知识之旅哟——初识JavaScript

这里是总结的一小点的web历史知识,并不知道有没有用:

• Mosaic是互联网历史上第一个普遍使用和能够显示图片的网页浏览器,1993年问世。

• 后来由于商标权的转让,原本的开发团队又开发了Netscape Navigator网景浏览器,也是现在很多浏览器的前身。

• js作为Netscape Navigator浏览器的一部分首次出现在1996年,它最初的设计目标是改善网页的用户体验,js的作者是Brendan Eich。

• 起初js被命名为LiveScript,后因为和Sun公司合作,Sun公司的Java很出名,因为市场宣传需要,所以改名为JavaScript,后来Sun公司被Oracle公司收购,因此js的版权现在归Oralcle所有。

浏览器的组成

前面提到过,浏览器主要有两部分组成:shell外壳部分和内核部分,其实内核还包括了很多东西。

1.渲染引擎,内核里的渲染引擎主要作用于html和css部分,定义了语法规则、渲染规则以及渲染路径和速度等等。

2.js引擎

2001年发布了ie6,首次实现对js引擎的优化。

2008年Google发布了Chrome,它是采用优化后的js引擎,引擎代号V8,因能把js代码直接转化成机械码0101来执行,进而以速度快而闻名。

后来Firefox也推出了具有强大功能的js引擎

Firefox 3.5 TraceMonkey(对频繁执行的代码做了路径优化)

Firefox 4.0 JeagerMonkey

3.其他模块。

JavaScript的特点

1.解释性语言——不需要编译代码,可以跨平台。

像php、js、jsp都是解释性语言。

2.单线程——js是单线程的语言,同时只能执行一件事情。

3.ECMA标准——为了统一js的规则,推出了ECMA标准,因此js也称为ECMAScript。

JavaScript执行队列

js中有一个重要的概念就是执行队列。

js只有一个主线程,它是单线程的。

其他模块把任务分解成好多的小模块,这些小模块排成一个队列,队列最前面的进入主线程执行,执行完之后第二个进入主线程执行,这个队列就是js的执行队列。有点像操作系统里面的轮转时间片。

JavaScript三大部分:ECMAScript、DOM、BOM

• ECMAScript是符合ECMA标准的基本javascript。

• DOM是Document Object Model文档对象模型,可以操作页面的代码,可以操作html和css部分。DOM是非常非常重要的部分。

• BOM是Browser Object Model浏览器对象模型,操作浏览器shell的。因为每一个浏览器厂家的不同,导致我们在每一个浏览器操作BOM都不一样,因此这里大概了解一下就可以了。

如何引入JavaScript代码

到这里我们大概了解javascript是什么东西了,那么我们如何在html页面里面引入js代码呢?

1.页面内嵌script标签

我们可以在<head>标签里面或者<body>标签里面写一个<script></script>,这个标签有一个type属性,如果要写的话就写完整的”text/javascript”,要不然就不写,浏览器会默认是这个type值,如果写还写错的话浏览器就会报错。

写完标签之后,我们就可以在这个标签里面写js代码了。

2.引入外部js文件

script标签除了可以在里面直接写代码之外,还可以写一个src属性来引入外部的js文件。

• 有一点值得注意的是,一个script标签只能在里面写代码或者引入外部js文件,不能既引入又在里面写代码。

• 一个script标签就是一个代码块,一个页面可以引入多个代码块。

• 为了符合传统页面的web标准(w3c标准的一项):结构、样式、行为相分离,我们一般采用第二种引入外部js文件的方法。我们的html、css、js最好放在专门的文件里面,然后在html里面引入外部文件。

• 浏览器在加载我们的html文件的时候,当遇到link标签的时候会异步加载,但是到script标签的时候并不会异步加载,而是会完全不加载后面的内容,而是去下载这个js文件,并且执行js文件里面的内容,之后下载并且执行完全部的js内容之后,浏览器才会继续执行html后面的代码。

这样就导致了一个问题,如果js是操作DOM的话,我们页面的DOM还没有出来,js就操作,就会出现错误,而且写在前面如果js文件比较大的话,就会导致页面一直没有内容。

因此,为了避免这种情况的出现,我们一般把script标签写在body标签里面的最后一行

JavaScript基本语法

变量声明

js是一种弱数据类型的语言,任何类型的变量都用关键字var来声明。



1. var arr = [1, 2, 3];
2. var num = 123;
3. var string = “abc”;
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

赋值可以在声明的同时赋值也可以在后面赋值。



1. var num = 123;
2. var num;
3. num = 123;
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这两种方法是一样的效果。

同时,我们有一种单一var模式,当我们要声明多个变量的时候,为了节省代码量,一般只写一个var:



1. var num1 = 123,
2.       num2 = 123,
3.       num3 = 123;
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

变量名要上下对齐,这样结构能加清晰,也能节省很多代码。

变量命名规则

1.以英文字母、_、$符号开头。

2.变量名可以包括数字。

3.不可以使用系统自带的关键字保留字作为变量名。

关键字是被系统定义了语法的单词,像var、window、if、else这一类都算作关键字。(关键字在编辑器里面是可以变色的)

保留字是为以后升级可能会变成关键字做的保留,像java、int、enum、abstract、short、boolean等等都是保留字。

值类型

js中的数据的值主要分为两大类:

1.不可改变的原始值

主要有:Number、String、Boolean、undefined、null

这些数据一般叫做栈数据

undefined是未定义的意思,而null是空的意思,他们俩的区别在于,null有值,不过这个值是空值,而undefined是未定义,完全没有值的意思。null一般用作占位。


1. var demo = null;
2. console.log(demo); // null
3. var a;
4. console.log(a); //undefined
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

我们在浏览器上按F12,打开控制台,就可以看到console.log的结果了。

2.引用值

主要有:数组array、对象object、函数function

这些数据一般叫做堆数据


1. var arr = [1, 2, 3, 4];
2. var object = {
3.       name: ‘demo’,
4.       age: ‘18’
5. }
6. console.log(arr); //1,2,3,4
7. console.log(object); //[Object Object]
8. console.log(object.name); // demo
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

那么这两种数据类型的区别在哪里呢?

我们举一个例子:


1. var num = 123,
2.       num1 = num;
3. num = 234;
4. console.log(num); //234
5. console.log(num1); //123
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

我们发现num的改变对num1完全没有影响。


1. var arr = [1, 2, 3],
2.       arr1 = arr;
3. arr.push(4);
4. arr.push(5);
5. console.log(arr); //1,2,3,4,5
6. console.log(arr1); //1,2,3,4,5
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

我们发现我们根本没有改变arr1的值,只是改变了arr的值,但是arr1也跟着改变了,这就是二者之间的第一个区别。

不过,如果我们是给arr重新赋值一个新的数组的话,那么arr1并不是这个新的数组。

arr = [1, 2, 3, 4, 5];

arr1 –> 1, 2, 3

这是为什么呢?

因为原始值是存放在栈里面的,而引用值是存放在堆里面的,原始值的赋值是把值的内容赋值一份给另一个变量,但是引用值却不是这样。引用值的变量名存在栈里面,但是值却是存在堆里面的,栈里面的变量名只是指向了一个堆空间,这个堆空间存的是我们一开始赋的值,当我们写arr1 = arr的时候,其实是把arr1指向了和arr指向的同一个的堆空间,这样当我们改变arr的内容的时候,其实就是改变了这个堆空间的内容,自然同样指向这个堆空间的arr1的值也随着改变了。

9q83czd7u5i8vxso

• 栈内存一点被赋值了,就不可以改变了,我们即使给num重新赋值为234,也是在栈里面重新开辟了一块空间赋值234,然后把num指向了这个空间,前面那个存放123的空间还存在,只是没有指针指向这里罢了。

第二点区别则是:原始值不可以被改变,引用值可以被改变。


1. var arr = [1, 2, 3, 4];
2. arr.length = 2;
3. console.log(arr); // 1,2
4. var str = “1234”;
5. str.length = 2;
6. console.log(str); // 1234
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这里涉及了一个包装类的概念,我们后面会提到。

JavaScript语句基本规则

1.语句后面要用英文分号结束 “;”

2.js语法错误会引发后面的代码终止,但不会影响其他的js代码块。这里仅限于逻辑错误,低级的语法错误会导致代码全都执行不了。

3.书写要规范,=、+、-、/、%两边都要留有空格。


1. num + 1;
2.  
3. num = num + 2;
4.  
5. num = num / 2;
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

一些公司还会有自己的其他编码规范,比如百度公司就会要求小括号和大括号左右两边留有空格。


1. for () {}
2.  
3. if () {}
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这些都是良好的编码习惯,养成这些习惯有助于我们以后的工作。

JavaScript运算符

算术运算符

  1.  + 运算符

• 数学上的相加功能

拼接字符串

字符串和任何数据相加都会变成字符串


1. var num = 1 + 2 + ‘3’;
2.  
3. console.log(num); //33
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

算术运算符的优先级是从左到右的。

2. – 运算符

• 数学上的相减功能

3. * 运算符

• 数学上的相乘功能

4. / 运算符

• 数学上的相除功能

  1. % 运算符

• 数学上的取余功能

  1. = 运算符

• 赋值运算符,优先级最低

7. == 运算符

• 比较运算符中的等于,不过两个等号的等于属于不严格等于,严格等于是“===”三个等号。

  1. () 运算符

• 和数学上一样,加括号的部分优先级最高


1. var num = 1 + ‘2’ + (1 + 1);
2.  
3. console.log(num); // 122
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

9. ++ 运算符

• 自加一运算,当写在变量前面的时候是先加1再执行运算,写在变量后面的时候是先运算再加1。


1. var num = 1;
2.  
3. console.log(num++); // 1
4.  
5. console.log(num); //2
6.  
7. console.log(++num); // 3
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

相类似的运算还有 ,用法和 ++ 一样,不过是减法操作。

  1. += 运算符

让变量加多少


1. var num = num + 10;
2.  
3. var num += 10;
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这两种操作是一样的效果,第二种是第一种的简写形式。

相同的还有 -=、/=、*-、%= 等等


1. var num = 3;
2.  
3. console.log(num %= 4); //3
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

比较运算符

比较运算符有 > 、< 、>= 、<= 、!= 、== 不严格等于、===严格等于

这里介绍一下不严格等于和严格等于的区别

当我们比较两个数据的时候,是先转化成同一个类型的数据之后再进行比较的。不严格等于就是说这两个数据进行了转化之后,他们的值相同,则整两个数据相等。而严格等于则是两个数据不进行数据转化也相等。


1. “2” === 2 // false
2.  
3. “2” == 2 //true
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

同时,NaN不等于任何数据,包括它本身,但是undefined就等于它本身。


1. NaN == NaN // false
2.  
3. undefined == undefined // true
4.  
5. var demo = !!“abc”; // true
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这里的demo要进行取反运算,先进行了类型转换为布尔值true,两次取反之后依然是true,这个可以用来作为数据转换成布尔值。

 逻辑运算符

逻辑运算符主要是 &&|| —— 与和或



1. var demo = 1 < 2 && 3; // 3
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

&&的作用是只有是true的时候,才会继续往后执行,一旦第一个表达式就错了,后面的第二个表达式根本不执行。如果表达式的返回结果都是true的话,那么这里&&的返回结果是最后一个正确的表达式的结果。样例中的demo是3。

||的作用是只要有一个表达式是true的,那么就结束,后面的就不走了,并且返回的结果是这个正确的表达式的结果,如果都是false的表达式的话,那么返回结果就是false。



1. var demo = 2 < 1 || (1 == 1); // true
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

一般来说,&&有当做短路语句的作用,因为运算符的运算特点,只有第一个条件成立的时候,才会运行第二个表达式,所以我们可以把简单的if语句用&&来表现出来。


1. if(flag) {console.log(‘hello’)};
2.  
3. flag && console.log(‘hello’);
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

这两个语句是同样的含义。

一般来说,||有当做赋初值的作用,有时候我们希望函数参数有一个初始值,再不使用ECMA6的语法的情况下,最好的做法就是利用或语句。


1. function demo (example) {
2.  
3.       var example = example || 100;
4.  
5. }
JavaScript; “复制代码”); “查看纯文本代码”); “返回代码高亮”)

当我们调用demo这个函数并且正确传值的时候,函数内部的变量example就是我们传的值,但是如果由于我们疏忽忘记传值的话,那么里面的example就是我们的默认值100。

不过这里也有一种缺点,当我们传的参数是一个布尔值的时候,并且传的是false,那么||语句的特点就会忽略掉我们传递的这个参数值而去赋成默认的初始值了,所以为了解决这个弊端,我们就需要利用es6的一些知识了。

 默认为false的值

数据中所有的值都可以被转换成true或false,但是true的值实在太多了,因此我们只需要记住false的值,其他的都是true。

默认为false:undefined、null、””、NaN、0、false

今天总结的知识点就这一些了,希望对大家有帮助哟~