快速入门基础
要让浏览器运行javaScript,必须先有一个HTML页面,在HTML页面中引入JavaScript,然后,让浏览器加载该HTML页面,就可以执行JavaScript代码
javaScript的语法和java类似,每个语句以“;”结束,语句块用{...}
但是JavaScript并不强制要求在每个语句的结尾加;
python的每个语句结尾则不需要加;
python也是脚本语言
浏览器中负责执行JavaScript代码的引擎会自动在每个语句的结尾补上;
让JavaScript引擎自动加分号在某些情况下会改变程序的语义,导致运行结果与期望不一致。
所以要养成加;的习惯
javaScript不区分整数和浮点数,统一用Number表示
由于JavaScript设计缺陷,不要使用==比较,始终坚持使用===比较
另一个例外是
NaN
这个特殊的Number与所有其他值都不相等,包括它自己JavaScript的对象是一组由键-值组成的无序集合,例如:
var person = { name: 'Bob', age: 20, tags: ['js', 'web', 'mobile'], city: 'Beijing', hasCar: true, zipcode: null };
JavaScript对象的键都是字符串类型,值可以是任意数据类型。
这种变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言,静态语言在定义变量时必须指定变量类型,如果赋值的时候不匹配,就会报错,例如java是静态语言。
如果一个变量没有通过var申明就被使用,那么该变量就自动申明为全局变量。
JavaScript为字符串提供了一些常用方法,注意,调用这些方法本身不会改变原有字符串的内容,而是返回一个新字符串
JavaScript的
Array
可以包含任意数据类型,并通过索引来访问每个元素。HTML定义了网页的内容
CSS描述了网页的布局
JavaScript控制了网页的行为。
JavaScript是web的编程语言
所有现代的HTML页面都是用JavaScript
由于JavaScript的对象是动态类型,你可以自由地给一个对象添加或删除属性
do { ... } while()
循环,它和while
循环的唯一区别在于,不是在每次循环开始的时候判断条件,而是在每次循环完成的时候判断条件用
do { ... } while()
循环要小心,循环体会至少执行1次,而for
和while
循环则可能一次都不执行。作为一个Web开发工程师来说,如果你想提供漂亮的网页、令用户满意的上网体验,JavaScript是必不可少的工具。
函数
请注意,函数体内部的语句在执行时,一旦执行到
return
时,函数就执行完毕,并将结果返回。如果两个不同的函数各自申明了同一个变量,那么该变量只在各自的函数体内起作用。换句话说,不同函数内部的同名变量互相独立,互不影响
由于JavaScript的函数可以嵌套,此时,内部函数可以访问外部函数定义的变量,反过来则不行,因为此时外部函数定义的变量对于内部函数来说就相当于全局变量。
为了解决块级作用域,ES6引入了新的关键字
let
,用let
替代var
可以申明一个块级作用域的变量编写高阶函数,就是让函数的参数能够接收别的函数
Array
的sort()
方法默认把所有元素先转换为String再排序默认情况下,对字符串排序,是按照ASCII的大小比较的
sort()
方法会直接对Array
进行修改,它返回的结果仍是当前Array
var a1 = ['B', 'A', 'C']; var a2 = a1.sort(); a1; // ['A', 'B', 'C'] a2; // ['A', 'B', 'C'] a1 === a2; // true, a1和a2是同一对象
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回
箭头函数的参数如果不是一个,就需要用括号
()
括起来箭头函数如果最外层是大括号
{}
,就不能省略return
面向对象编程
在JavaScript中,字符串也区分
string
类型和它的包装类型。包装对象用new
创建虽然包装对象看上去和原来的值一模一样,显示出来也是一模一样,但他们的类型已经变为
object
了!所以,包装对象和原始值用===
比较会返回false
JavaScript的原型链和Java的Class区别就在,它没有“Class”的概念,所有对象都是实例,所谓继承关系不过是把一个对象的原型指向另一个对象而已
在编写JavaScript代码时,不要直接用
obj.__proto__
去改变一个对象的原型JavaScript规定,每一个构造函数都有一个prototype属性,指向另一个对象,这个对象的所有属性和方法,都会被构造函数的实例继承。
也就是说,JavaScript里,继承的对象,可以通过构造函数的实例继承。
用
new
来调用构造函数,实际上在这里构造函数就相当于是java里的类,所以在JavaScript里构造函数约定用大写开头。用
new
来调用构造函数,返回的对象就是实例。只不过在java里的实例化对象指的是将抽象类实例化,这里是将构造的抽象的构造函数实例化一个对象出来。所以有构造函数的实例这种说法。
我们可以把那些不变的方法和属性,直接定义在prototype对象上。
isPrototypeOf()
这个方法用来判断某个prototype对象和某个实例之间的关系prototype
是构造函数的属性,指向的是另一个对象,这个对象的所有属性和方法会被构造函数的实例所继承。可以理解为构造函数的这个prototype属性是构造函数实例化之后的对象的原型。
alert(Cat.prototype.isPrototypeOf(cat1)); //true alert(Cat.prototype.isPrototypeOf(cat2)); //true
hasOwnProperty()
每个实例对象都有一个
hasOwnProperty()
方法,用来判断某一个属性到底是本地属性,还是继承自prototype
对象的属性。alert(cat1.hasOwnProperty("name")); // true
alert(cat1.hasOwnProperty("type")); // false
构造函数可以看作是java里的类,所以,调用构造函数千万不要忘记写
new
。为了区分普通函数和构造函数,按照约定,构造函数首字母应当大写Cat.prototype = new Animal(); Cat.prototype.constructor = Cat; var cat1 = new Cat("大毛","黄色"); alert(cat1.species); // 动物
任何一个构造函数的prototype对象都有一个constructor属性,又指向这个构造函数。如果没有"Cat.prototype = new Animal();"这一行,Cat.prototype.constructor是指向Cat的,加了这一行以后,Cat.prototype.constructor指向Animal。因此我们必须手动纠正,将Cat.prototype对象的constructor值改为Cat。这就是第二行的意思。
如果替换了prototype对象,那么下一步必然是为新的prototype对象加上constructor属性,并将这个属性指回原来的构造函数。
以上部分实例是变量,类是函数。
class
ES6引入的
class
和原有的JavaScript原型继承有什么区别呢?实际上它们没有任何区别,class
的作用就是让JavaScript引擎去实现原来需要我们自己编写的原型链代码。简而言之,用class
的好处就是极大地简化了原型链代码。
浏览器
cookie
服务器区分是哪个用户发送的请求。
当一个用户成功登录后,服务器发送一个cookie给浏览器,此后,浏览器访问该网站时,会在请求头(header)上附上这个cookie。服务器根据浏览器附上的cookie即可区分出用户。
由于ID在HTML文档中是唯一的,所以
document.getElementById()
可以直接定位唯一的一个DOM节点HTML
HTML是一种标记性语言,超文本标记语言,所谓超文本,顾名思义就是除了文字,还可以包含图形、动画、声音、链接等非文字元素。HTML文档就是一系列的Tag组成,由于HTML是富文档模型,所以,还有一系列的Tag用来表示链接、图片、表格、表单等等。
自然语言是人与人之间交流的语言,而HTML是人与浏览器之间交流的语言
通过HTML命令告诉浏览器,在网页的哪个位置有什么控件,而控件的样式,控件的功能,则分别需要CSS和JavaScript来实现。
CSS
CSS(英文全称:Cascading Style Sheets),中文全称:层叠样式表
是一种用来表现HTML和XML等文件样式的计算机语言
CSS 能够对网页中元素位置的排版进行像素级精确控制,支持几乎所有的字体字号样式,拥有对网页对象和模型样式编辑的能力。
CSS用来控制HTML里的所有元素如何展现,比如,给标题元素
<h1>
加一个样式,变成48号字体,灰色,带阴影也就是说HTML能确定一个页面上大致有些什么内容,CSS决定具体的控件的样式和布局、美化方面。而控件的逻辑,前后端接口调用等逻辑由JavaScript来写。VUE框架里面包含了这些东西。
javaScript
JavaScript(简称:JS)是一种直译式高级脚本语言,常用来为网页添加各式各样的复杂动态功能,为用户提供更流畅美观的浏览效果。通常JavaScript脚本是通过嵌入在HTML中来实现自身的功能的。
markdown
markdown和HTML都是标记性语言,不同点在于,markdown是文本语言,HTML除了文字还有别的图形动画声音等非文字元素。
HTML加上CSS、JavaScript呈现出我们最终看到的网页
jQuery
层级选择器
如果两个DOM元素具有层级关系,就可以用
$('ancestor descendant')
来选择,层级之间用空格隔开。子选择器
子选择器
$('parent>child')
类似层级选择器,但是限定了层级关系必须是父子关系,就是<child>
节点必须是<parent>
节点的直属子节点。选择器是jQuery的核心
实际上,jQuery把所有方法也就是功能都封装在一个全局变量中,这个全局变量就是jQuery,而
$
也是一个合法的变量名,是jQuery的别名通常情况下,选择器可以直接定位到我们想要的元素,但是,当我们拿到一个jQuery对象后,还可以以这个对象为基准,进行查找和过滤。
jQuery是一个JavaScript库,极大地简化了JavaScript的编程。
在jQuery中,$( )是其运行环境;
由于不同浏览器绑定事件的代码不太一样,所以用jQuery来写代码,就屏蔽了不同浏览器之间的差异,总是编写相同的代码。
on方法用来绑定一个事件,需要传入事件名称和对应的处理函数。
a.on('click', function () { alert('Hello!'); });
用JavaScript实现动画的原理:
我们只需要以固定的时间间隔(例如 0.1s),每次把DOM元素的CSS样式修改一点,看起来就像动画了。
animate()
可以实现任意动画效果,我们需要传入的参数就是DOM元素最终的CSS状态和时间,jQuery在时间段内不断调整CSS直到达到我们设定的值jQuery的原理是逐渐改变CSS的值。但是很多不是block性质的DOM元素,对它们设置
height
根本就不起作用,所以动画也就没有效果。编写jQuery插件的原则:
- 给
$.fn
绑定函数,实现插件的代码逻辑 - 插件函数要
return this;
以支持链式调用 - 插件函数要有默认值,绑定在
$.fn.<pluginName>.defaults
上; - 用户在调用时可传入设定值以便覆盖默认值。
- 给
jQuery对象的有些方法只能作用在特定DOM元素上,比如
submit()
方法只能针对form
。Node.js平台是在后端运行JavaScript代码
node.js
注意区分命令行模式和交互模式。
命令行模式就可以理解为安装好jdk之后,从windows命令行进行运行程序的操作。
java xxx.java
node xxx.js
python xxx.py
交互模式就像python的IDLE那样,写一行会编译一行,也可以说是解释一行,因为python和js都是脚本型语言。
看到类似
C:\>
是在Windows提供的命令行模式在命令行模式下,可以执行
node
进入Node交互式环境,也可以执行node hello.js
运行一个.js
文件。看到
>
是在Node交互式环境下在Node交互式环境下,我们可以输入JavaScript代码并立刻执行。
在命令行模式运行
.js
文件和在Node交互式环境下直接运行JavaScript代码有所不同。Node交互式环境会把每一行JavaScript代码的结果自动打印出来,但是,直接运行JavaScript文件却不会。直接输入
node
进入交互模式,相当于启动了Node解释器,但是等待你一行一行地输入源代码,每输入一行就执行一行。(类似于python解释器,IDLE)直接运行
node hello.js
文件相当于启动了Node解释器,然后一次性把hello.js
文件的源代码给执行了,你是没有机会以交互的方式输入源代码的。VS Code以文件夹作为工程目录(Workspace Dir),所有的JavaScript文件都存放在该目录下。此外,VS Code在工程目录下还需要一个
.vscode
的配置目录,里面存放里VS Code需要的配置文件。为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。
在Node环境中,一个.js文件就称之为一个模块(module)。
在python环境中,一个.py文件就称之为一个模块,多个模块即多个.py文件组成一个包
模块即.py文件就是用来导入的,就像在java环境中一个.java文件大多是一个类,用来在别的程序中import。
import了某个类,那么就可以用那个类中的方法。
要在模块中对外输出变量,用:
module.exports = variable;
输出的变量可以是任意对象、函数、数组等等。
要引入其他模块输出的对象,用:
var foo = require('other_module');
引入的对象具体是什么,取决于引入模块输出的对象。
node.js是运行在服务器端的JavaScript环境
服务器程序与浏览器程序相比,最大的特点就是没有浏览器的安全限制了。
在服务端通过node.js运行程序,和通过浏览器来运行程序是不同的,这里的通过浏览器运行程序除了字面意思,也就是通过edge、chrome等,在开发者模式下的控制台直接写JavaScript代码可以运行程序,还是指在vscode中,通过debugger for edge、debugger for chrome来运行程序。
运行程序的时候,通过node.js还是debugger for edge,这是不同的,运行环境不同,一个是在服务器端运行,一个是在浏览器端运行,比如在浏览器中可以顺利运行,而在服务器端不可以,这是因为node.js环境没有浏览器环境的相关变量之类的东西。(比如说window这个变量,jQuery的$)。
JavaScript有且仅有一个全局对象,在浏览器环境,叫
window
对象而在node.js环境中,叫
global
,这也是为什么在js文件中写window对象不会报错,但是直接通过codeRunner运行这个js文件会报错的原因,因为直接运行js文件,导致根本就不是一个环境,没有这个window
对象,通过node.js运行,当然会报错。出现这种错误还是对js运行环境,基础的不了解。global
这个对象的属性和方法也和浏览器环境的window
不同有很多JavaScript代码既能在浏览器中执行,也能在Node环境执行,但有些时候,程序本身需要判断自己到底是在什么环境下执行的,常用的方式就是根据浏览器和Node环境提供的全局变量名称来判断:
if (typeof(window) === 'undefined') { console.log('node.js'); } else { console.log('browser'); }
同步读文件和异步读文件的区别
异步读文件
'use strict'; var fs = require('fs'); fs.readFile('sample.png', function (err, data) { if (err) { console.log(err); } else { console.log(data); console.log(data.length + ' bytes'); } });
同步读文件
'use strict'; var fs = require('fs'); var data = fs.readFileSync('sample.txt', 'utf-8'); console.log(data);
fs
也提供相应的同步读取函数。同步读取的函数和异步函数相比,多了一个Sync
后缀,并且不接收回调函数,函数直接返回结果。可见,原异步调用的回调函数的
data
被函数直接返回,函数名需要改为readFileSync
,其它参数不变。stream
标准输入流,字符从键盘输入到应用程序
标准输出流,字符从应用程序输出到键盘
流的特点是数据是有序的,而且必须依次读取,或者依次写入,不能像Array那样随机定位。
在Node.js中,流也是一个对象,我们只需要响应流的事件就可以了:
data
事件表示流的数据已经可以读取了,end
事件表示这个流已经到末尾了,没有数据可以读取了,error
事件表示出错了。
web开发
软件主要运行在桌面上,采用的模式是CS架构模式即client/server架构模式。这种模式简称CS架构
软件是在桌面上作为客户端运行,而数据库这样的软件运行在服务端作为server
这种CS架构模式并不适合web,因为web应用程序的修改和升级都非常迅速,因为CS架构的方式都是通过客户端升级的方式来升级桌面APP(client),客户端不断升级这种方式显然对于浏览器和web来说不适合。
因此,Browser/server模式开始流行,简称B/S架构。
在BS架构下,客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器,获取Web页面,并把Web页面展示给用户即可。所以当服务端升级后,客户端无需做任何升级就可以使用到新的版本。因为更新的web页面是服务器给客户端(浏览器)的
web页面使用HTML写的,HTML具有超强的表现力,是超文本语言,也就是说HTML不只是文字,还有图片、声音、超链接等等。和MARKDOWN一样都是标记性语言。
Web应用特点是修改频繁
在web应用中,服务器把网页传给客户端即浏览器,实际上是把网页的HTML代码发送给浏览器,让浏览器显示出来,而浏览器和服务器之间的传输协议是HTTP。
HTML是一种用来定义网页的文本,会HTML,就可以编写网页;
HTTP是在网络上传输HTML的协议,用于浏览器和服务器的通信。
当浏览器读取到HTML源码后,也就是浏览器发送请求(request)给服务器之后,服务器会发送对应的响应给浏览器,在F12控制台页面,可以查看到浏览器会有相应的响应。
request是客户端发送给浏览器的请求,包含header、Content-Type等等,在代码里也经常会写给服务器发送请求,所以这里的客户端除了指浏览器,还有我们编写的代码。对于浏览器来说,服务器就是字面意思的服务器,对于我们有时候一个程序需要调用另一个程序的接口,用到请求httpRequest,这时候服务器就相当于另一个程序。根据Code来判断请求是否成功以及是客户端还是服务端出了问题。
比如说前端网页发送请求给后端,这显然说的就是浏览器发送请求request给服务器,服务器给出对应的响应,浏览器接收到响应,响应可以在开发者界面查看到。
核心就是A发送请求给B,那么A就是作为客户端,B就是作为服务端,根据错误码可以判断是哪一端出了问题。
这里一直在说浏览器和服务器,实际也就是客户端和服务器,HTTP就是他们双方之间通信的协议。
浏览器获得响应后,得到HTML源码后,会解析HTML并显示页面,然后根据HTML页面里面的各种链接,再发送HTTP请求给服务器,拿到相应的图片、视频、Flash、JavaScript脚本、CSS等各种资源,最终显示出一个完整的页面。所以我们在
Network
下面能看到很多额外的HTTP请求。开发者界面的Network这个选项就是查看浏览器(客户端)和服务端之间的通信的。
客户端<->服务端
前端<->后端
可以把服务器理解为后端,仍然需要程序代码支撑,这就是后端开发。
Elements
显示网页的结构,Network
显示浏览器和服务器的通信。总结HTTP Request的流程
浏览器首先向服务器发送http request,request包括
- 方法:
GET
还是POST
,GET
仅请求资源,POST
会附带用户数据 - 路径
- 域名:由Host头指定:
Host: www.sina.com.cn
- 如果是
POST
,那么请求还包括一个Body,包含用户数据。
- 方法:
服务器(后端,前端后端都涉及到代码开发。服务器怎么返回,根据前端的request返回什么内容、什么格式、怎么处理前端的请求,这些都是后端开发需要考虑的内容。这些就相当于是后端考虑,前端就不需要考虑了,只管发送请求,相当于是服务器为浏览器的请求提供了接口,也就是API)
服务器向浏览器返回HTTP响应,响应包括:
- 响应代码
200
表示成功,3xx
表示重定向,4xx
表示客户端发送的请求有错误,5xx
表示服务器端处理时发生了错误;(4xx
也是开发的时候最经常遇到的错误,说明客户端的请求有错误,但是这里不是说一定是客户端发送的请求内容错了,而是客户端相对于服务器来说,请求有错误,比如说服务端的程序提供的接口内部有bug,正确的请求内容发送过去肯定也是返回4xx
错误,因为客户端的请求让服务端返回了错误响应,所以是4xx
错误。5xx
错误一般是我们在开发过程中管不了的) - 响应类型,由
Content-Type
指定,例如:Content-Type: text/html;charset=utf-8
表示响应类型是HTML文本,并且编码是UTF-8
,Content-Type: image/jpeg
表示响应类型是JPEG格式的图片; - 以及其他相关的Header;
- 通常服务器的HTTP响应会携带内容,也就是有一个Body,包含响应的内容,网页的HTML源码就在Body中。
- 响应代码
如果浏览器还需要继续向服务器请求其他资源,比如图片,就再次发出HTTP请求,重复步骤1、2。
Web采用的HTTP协议采用了非常简单的请求-响应模式,从而大大简化了开发。
HTTP协议同时具备极强的扩展性,虽然浏览器请求的是
http://www.sina.com.cn/
的首页,但是新浪在HTML中可以链入其他服务器的资源,比如<img src="http://i1.sinaimg.cn/home/2013/1008/U8455P30DT20131008135420.png">
,从而将请求压力分散到各个服务器上,并且,一个站点可以链接到其他站点,无数个站点互相链接起来,就形成了World Wide Web,简称“三达不溜”(WWW)。每个HTTP请求和响应都遵循相同的格式,一个HTTP包含Header和Body两部分
服务器返回的响应的body类型由
Content-Type
指定HTML文档就是一系列的Tag组成