Javascript学习笔记

一、Javascript简介:

JavaScript是一种属于网络的解释型的脚本语言,已经被广泛用于Web应用开发。最早是在HTML网页上使用,用来给HTML网页增加各式各样的动态功能。在过去,JavaScript只是被用来做一些简单的网页效果,比如表单验证、浮动广告等,所以那时候JavaScript并没有受到重视。自从AJAX开始流行后,人们发现利用JavaScript可以给用户带来更好的体验,甚至利用这一优点开发了大型网页游戏,于是这门语言被重视了起来。

二、Javascript代码存放的位置

1、JavaScript代码可以直接嵌在网页的任何地方,不过通常我们把Javascript代码放在中。
2、可以将JavaScript代码放到一个单独.js文件中,如将文件命名为:script.js那么引用方式为:

 <script type = "text/javascript" src = "script.js" />

三、Javascript中的数据类型

Javascript脚本语言同其他语言一样,有它自身的基本数据类型,表达式和算术运算符及程序的基本程序框架。Javascript提供了五种基本的数据类型

Number、String、Boolean、nullundefined

两种特殊数据类型

Array、Object

用来处理数据和文字。

1、Number

JavaScript不区分整数和浮点数,统一用Number表示。Number可以直接做四则运算。

2、String

字符串是以单引号 ’ 或双引号 " 括起来的任意文本,比如’abc’,“xyz"等等。需注意,''或”"本身只是一种表示方式,不是字符串的一部分,因此,字符串’abc’只有a,b,c这3个字符。

3、Boolean

布尔值和布尔代数的表示完全一致,一个布尔值只有true、false两种值,要么是true,要么是false。

4、Null

null表示一个“空”的值,它和0以及空字符串’‘不同,0是一个数值,’'表示长度为0的字符串,而null表示“空”。

5、Undefined

在JavaScript中,还有一个和null类似的undefined,它表示“未定义”。

6、Arrary 数组

数组是一组按顺序排列的集合,集合的每个值称为元素。JavaScript的数组可以包括任意数据类型。例如:

[1, 2, 3.14, 'Hello', null, true];
7、Object 对象

JavaScript的对象是一组由键-值组成的无序集合。JavaScript对象的键都是字符串类型,值可以是任意数据类型。例如:

var person = {
    name: 'Bob',
    age: 20,
    tags: 'js', 'web', 'mobile'],
    city: 'Beijing',
    hasCar: true,
};

Javascript 标识符可以使用数字、大小写字母,下划线,美元符号构成,标识符不能以数字开头。JavaScipt严格区分大小写,代码必须以分号结束。

四、Javascript中的****函数

1、方法

在一个对象中绑定函数,称为这个对象的方法。
在JavaScript中,对象的定义是这样的:

var xiaoming = {
     name: '小明',
     birth: 1990
};

但是,如果我们给xiaoming绑定一个函数,就可以做更多的事情。比如,写个age()方法,返回xiaoming的年龄:

var xiaoming = {
     name: '小明',
     birth: 1990,
     age: function () {
         var y = new Date().getFullYear();
         return y - this.birth;
     }
};
xiaoming.age; 
xiaoming.age(); 
2、高阶函数

JavaScript的函数其实都指向某个变量。既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

(1)、 map()
举例说明,比如我们有一个函数f(x)=x*x,要把这个函数作用在一个数组[1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map实现如下:

function pow(x) {
     return x * x;
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81]

由于map()方法定义在JavaScript的Array中,我们调用Array的map()方法,传入我们自己的函数,就得到了一个新的Array作为结果:

(2)、 reduce()

Array的reduce()把一个函数作用在这个Array的[x1, x2, x3...]上,这个函数必须接收两个参数,reduce()把结果继续和序列的下一个元素做累积计算,

比方说对一个Array求和,就可以用reduce实现:
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
     return x + y;
}); // 25

(3)、 filter()

filter也是一个常用的操作,它用于把Array的某些元素过滤掉,然后返回剩下的元素。

和map()类似,Array的filter()也接收一个函数。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。

例如,在一个Array中,删掉偶数,只保留奇数,可以这么写:

var arr = [1, 2, 4, 5, 6, 9, 10, 15];
var r = arr.filter(function (x) {
     return x % 2 !== 0;
});
r; // [1, 5, 9, 15]

(4)、 sort()

JavaScript的Array的sort()方法就是用于排序的,但是排序结果可能让你大吃一惊:

// 看上去正常的结果:
['Google', 'Apple', 'Microsoft'].sort(); // ['Apple', 'Google', 'Microsoft'];

// apple排在了最后:
['Google', 'apple', 'Microsoft'].sort(); // ['Google', 'Microsoft", 'apple']

// 无法理解的结果:
[10, 20, 1, 2].sort(); // [1, 10, 2, 20]

这是因为Array的sort()方法默认把所有元素先转换为String再排序。sort()方法也是一个高阶函数,它还可以接收一个比较函数来实现自定义的排序。

例如:要按数字大小排序,我们可以这么写:

var arr = [10, 20, 1, 2];
arr.sort(function (x, y) {
    if (x < y) {
        return -1;
    }
    if (x > y) {
        return 1;
    }
    return 0;
}); // [1, 2, 10, 20]
2、闭包

闭包(closure)定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函数内部变量的函数。

由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

闭包的用处,一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

(1)、读取函数内部的变量

例如:

function f1(){
    var n=999;
  function f2(){
    alert(n);
  }
return f2;
}
var result=f1();
result(); // 999

把f2作为返回值,我们就可以在f1外部读取它的内部变量

(2)、将变量的值始终保持在内存中

例如:

function f1() {
    var n = 999;
    nAdd = function () { n += 1 }
    function f2() {
        alert(n);
    }
    return f2;
}
var result = f1();
result(); // 999
nAdd();
result(); // 1000

在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制回收。

4、箭头函数

ES6标准新增了一种新的函数:Arrow Function(箭头函数)。

为什么叫Arrow Function?因为它的定义用的就是一个箭头:

x => x * x
//上面的箭头函数相当于:
function (x) {
    return x * x;
}

箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式,一种像上面的,只包含一个表达式,连{ … }和return都省略掉了。还有一种可以包含多条语句,这时候就不能省略{ … }和return:

x => {
     if (x > 0) {
         return x * x;
     }
     else {
         return - x * x;
     }
}
//如果参数不是一个,就需要用括号()括起来:
(x, y) => x * x + y * y
5、generator

generator(生成器)是ES6标准引入的新的数据类型。一个generator看上去像一个函数,但可以返回多次。

generator跟函数很像,定义如下:

function* foo(x) {
     yield x + 1;
     yield x + 2;
     return x + 3;
}

generator和函数不同的是,generator由function定义(注意多出的号),并且,除了return语句,还可以用yield返回多次。

五、标准对象

1、Date

在JavaScript中,Date对象用来表示日期和时间。

要获取系统当前时间,用:

var now = new Date();
now;//Tue Nov 01 2020 11:34:14 GMT+0800(中国标准时间)
now.getFullYear(); // 2020 年份
now.getMonth(); // 10, 月份,注意月份范围是0~11,10表示11月
now.getDate(); // 1, 表示1号
now.getDay(); // 2, 表示星期二
now.getHours(); // 11, 24小时制
now.getMinutes(); // 30, 分钟
now.getSeconds(); // 22, 秒
now.getMilliseconds(); // 490, 毫秒数
now.getTime(); // 1477971254490, 以number形式表示的时间戳

注意,当前时间是浏览器从本机操作系统获取的时间,所以不一定准确,因为用户可以把当前时间设定为任何值。
如果要创建一个指定日期和时间的Date对象,可以用:

var d = new Date(2016, 5, 19, 20, 15, 30, 123);
d; // Fri Jun 19 2016 20:15:30 GMT+0800 (CST)
2、RegExp

正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。

在javascript我们可以通过内建的类来定义一个正则表达式。

var reName = new RegExp();

在javascript中处理正则表达式的方法。

test – RegExp的test方法用来测试字符串是否匹配给出的匹配模式,返回布尔值;

exec – RegExp的exec方法返回包含第一个匹配的的数组或null;

match – String的match方法返回包含所有匹配子字符串的数组;

replace – String的replace方法完成string的替换操作,支持正则表达式;

search – 与String的indexof方法类似,不同的是search支持正则表达式,而不仅仅是字符串;

split – 按照一定规则拆分字符串并将子字符串存储到数组中的String方法。

关于这些函数的具体使用方法,可以参阅JS的相关函数手册。

3、JSON

JSON是JavaScript Object Notation的缩写,它是一种数据交换格式。在JSON中有以下几种数据类型:

number:和JavaScript的number完全一致;

boolean:就是JavaScript的true或false;

string:就是JavaScript的string;

null:就是JavaScript的null;

array:就是JavaScript的Array表示方式——[];

object:就是JavaScript的{ … }表示方式。

以及上面的任意组合。

并且,JSON还定死了字符集必须是UTF-8,表示多语言就没有问题了。为了统一解析,JSON的字符串规定必须用双引号"“,Object的键也必须用双引号”"。

序列化
让我们先把小明这个对象序列化成JSON格式的字符串:

var xiaoming = {
     name: '小明',
     age: 14,
     gender: true,
     height: 1.65,
     grade: null,
    'middle-school': '\"W3C\" Middle School',
     skills: ['JavaScript', 'Java', 'Python', 'Lisp']
};
JSON.stringify(xiaoming,null,’’);
结果:
{
   "name": "小明",
   "age": 14,
   "gender": true,
   "height": 1.65,
   "grade": null,
   "middle-school": "\"W3C\" Middle School",
   "skills": [
     "JavaScript",
     "Java",
     "Python",
     "Lisp"
   ]
}

第二个参数用于控制如何筛选对象的键值,如果我们只想输出指定的属性,可以传入Array:

JSON.stringify(xiaoming, ['name', 'skills'], '  ');
结果:
{
    "name": "小明",
   "skills": [
     "JavaScript",
     "Java",
     "Python",
     "Lisp"
    ]
}

六、面向对象编程

JavaScript的所有数据都可以看成对象,不区分类和实例的概念,而是通过原型(prototype)来实现面向对象编程。

1、创建对象的几种方法

(1)、使用对象字面量的方式{}创建一个对象

var Cat  = {};
Cat.name="kity";//添加属性并赋值
Cat.age=2;
Cat.sayHello=function(){
 alert("hello "+Cat.name+",今年"+Cat["age"]+"岁了");//可以使用“.”的方式访问属性,也可以使用HashMap的方式访问
}
Cat.sayHello();//调用对象的(方法)函数

(2)、用构造函数创建对象

function Person(){
}
var personOne=new Person();//定义一个function,如果有new关键字去"实例化",那么该function可以看作是一个类
personOne.name="dylan";
personOne.hobby="coding";
personOne.work=function(){
alert(personOne.name+" is coding now...");
}
personOne.work();

(3)、使用原型模式创建对象

function Dog(){
 }
 Dog.prototype.name="旺财";
 Dog.prototype.eat=function(){
 alert(this.name+"是个吃货");
 }
var wangcai =new Dog();
wangcai.eat();
2、class继承

新的关键字class从ES6开始正式被引入到JavaScript中。class的目的就是让定义类更简单。

如果用新的class关键字来编写Student,可以这样写:

class Student {
     constructor(name) {
         this.name = name;
     }
     hello() {
         alert('Hello, ' + this.name + '!');
     }
}

用class定义对象的一个巨大的好处是继承更方便。现在,原型继承的中间对象,原型对象的构造函数等等都不需要考虑了,直接通过extends来实现:

class PrimaryStudent extends Student {
     constructor(name, grade) {
         super(name); // 记得用super调用父类的构造方法!
         this.grade = grade;
     }
      myGrade() {
         alert('I am at grade ' + this.grade);
     }
}

ES6引入的class和原有的JavaScript原型继承有什么区别呢?

实际上它们没有任何区别,class的作用就是让JavaScript引擎去实现原来需要我们自己编写的原型链代码。简而言之,用class的好处就是极大地简化了原型链代码。

七、浏览器

由于JavaScript的出现就是为了能在浏览器中运行,所以,浏览器自然是JavaScript开发者必须要关注的。

1、浏览器对象

(1)、window

window对象不但充当全局作用域,而且表示浏览器窗口。

(2)、navigator

navigator对象表示浏览器的信息,最常用的属性包括:

navigator.appName:浏览器名称;

navigator.appVersion:浏览器版本;

navigator.language:浏览器设置的语言;

navigator.platform:操作系统类型;

navigator.userAgent:浏览器设定的User-Agent字符串。

(3)、screen

screen对象表示屏幕的信息,常用的属性有:

screen.width:屏幕宽度,以像素为单位;

screen.height:屏幕高度,以像素为单位;

screen.colorDepth:返回颜色位数,如8、16、24。

(4)、document

document对象表示当前页面。由于HTML在浏览器中以DOM形式表示为树形结构,document对象就是整个DOM树的根节点。

(5)、history

history对象保存了浏览器的历史记录,JavaScript可以调用history对象的back()或forward (),相当于用户点击了浏览器的“后退”或“前进”按钮。

2、操作DOM

(1)、更新DOM

一种是修改innerHTML属性,这个方式非常强大,不但可以修改一个DOM节点的文本内容,还可以直接通过HTML片段修改DOM节点内部的子树:

// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置文本为abc:
p.innerHTML = 'ABC'; // <p id="p-id">ABC</p>
// 设置HTML:
p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ';
// <p>...</p>的内部结构已修改

第二种是修改innerText或textContent属性,这样可以自动对字符串进行HTML编码,保证无法设置任何HTML标签:

// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置文本:
p.innerText = '<script>alert("Hi")</script>';

两者的区别在于读取属性时,innerText不返回隐藏元素的文本,而textContent返回所有文本。另外注意IE<9不支持textContent。

(2)、插入DOM

如果这个DOM节点是空的,例如,

,那么,直接使用innerHTML = ' child'就可以修改DOM节点的内容,相当于“插入”了新的DOM节点。

如果这个DOM节点不是空的,那就不能这么做,因为innerHTML会直接替换掉原来的所有子节点。可以使用appendChild,把一个子节点添加到父节点的最后一个子节点。例如:

<!-- HTML结构 -->
<p id="js">JavaScript</p>
<div id="list">
     <p id="java">Java</p>
     <p id="python">Python</p>
    <p id="scheme">Scheme</p>
</div>

JavaScript

添加到
的最后一项:
Var js = document.getElementById('js'),
list = document.getElementById('list');
list.appendChild(js);

现在,HTML结构变成了这样:

<!-- HTML结构 -->
<div id="list">
     <p id="java">Java</p>
     <p id="python">Python</p>
     <p id="scheme">Scheme</p>
     <p id="js">JavaScript</p>
</div>

(3)、删除DOM

要删除一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的removeChild把自己删掉:
// 拿到待删除节点:
var self = document.getElementById('to-be-removed');
// 拿到父节点:
var parent = self.parentElement;
// 删除:
var removed = parent.removeChild(self);
removed === self; // true
3、操作表单

(1)、获取值

如果我们获得了一个节点的引用,就可以直接调用value获得对应的用户输入值:

var input = document.getElementById('email');
input.value; // '用户输入的值'
//这种方式可以应用于text、password、hidden以及select。

(2)、设置值

设置值和获取值类似,对于text、password、hidden以及select,直接设置value就可以:

var input = document.getElementById('email');
input.value = 'test@example.com'; // 文本框的内容已更新
4、操作文件

JavaScript可以在提交表单时对文件扩展名做检查,以便防止用户上传无效格式的文件:

var f = document.getElementById('test-file-upload');
var filename = f.value; // 'C:\mypath\test.png'
if(!filename||!(filename.endsWith('.jpg')||filename.endsWith('.png') || filename.endsWith('.gif'))) {
    alert('Can only upload image file.');
    return false;
}
5、AJAX

AJAX不是JavaScript的规范,它是Asynchronous JavaScript and XML的缩写,意思就是用JavaScript执行异步网络请求。
用JavaScript写一个完整的AJAX代码并不复杂,但是需要注意:AJAX请求是异步执行的,也就是说,要通过回调函数获得响应。
在现代浏览器上写AJAX主要依靠XMLHttpRequest对象:

function success(text) {
    Var textarea = document.getElementById('test-response-text');
    textarea.value = text;
}
function fail(code) {
    var textarea = document.getElementById('test-response-text');
    textarea.value = 'Error code: ' + code;
}
var request = new XMLHttpRequest(); // 新建XMLHttpRequest对象
request.onreadystatechange = function () { // 状态发生变化时,函数被回调
    if (request.readyState === 4) { // 成功完成
        // 判断响应结果:
        if (request.status === 200) {
            // 成功,通过responseText拿到响应的文本:
            return success(request.responseText);
        } else {
            // 失败,根据响应码判断失败原因:
            return fail(request.status);
        }
    } else {
        // HTTP请求还在继续...
    }
}
// 发送请求:
request.open('GET', '/api/categories');
request.send();
alert('请求已发送,请等待响应...');
5、Promise

Promise是异步编程的一种解决方案,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise是一个对象,从它可以获取异步操作的消息。Promise提供统一的API,各种异步操作都可以用同样的方法进行处理。
下面是一个Promise对象的简单例子:

function timeout(ms) {
   return new Promise((resolve, reject) => {
     setTimeout(resolve, ms, 'done');
   });
}
timeout(100).then((value) => {
   console.log(value);
});

上面代码中,timeout方法返回一个Promise实例,表示一段时间以后才会发生的结果。过了指定的时间(ms参数)以后,Promise实例的状态变为Resolved,就会触发then方法绑定的回调函数。
下面是异步加载图片的例子:

function loadImageAsync(url) {
   return new Promise(function(resolve, reject) {
     var image = new Image();
     image.onload = function() {
       resolve(image);
     };

    image.onerror = function() {
       reject(new Error('Could not load image at ' + url));
     };
     image.src = url;
   });
}

上面代码中,使用Promise包装了一个图片加载的异步操作。如果加载成功,就调用resolve方法,否则就调用reject方法。

八、JQuery

jQuery是JavaScript在世界上使用最广泛的一个库。
jQuery为我们解决了一些很重要的问题。jQuery能帮我们干这些事情:
a. 消除浏览器差异:你不需要自己写冗长的代码来针对不同的浏览器来绑定事件,编写AJAX等代码;
b.简洁的操作DOM的方法:写$(‘#test’)肯定比document.getElementById(‘test’)来得简洁;
c. 轻松实现动画、修改CSS等各种操作。

1、基本选择器

选择器是jQuery的核心。一个选择器写出来类似$(‘#dom-id’)。
(1)、按ID查找
如果某个DOM节点有id属性,利用jQuery查找如下:

// 查找<div id="abc">:
var div = $('#abc');

(2)、按tag查找

按tag查找只需要写上tag名称就可以了:

var ps = $('p'); // 返回所有<p>节点
ps.length; // 数一数页面有多少个<p>节点

(3)、按class查找

按class查找注意在class名称前加一个:

var a = $('.red'); // 所有节点包含class="red"都将返回
// 例如:
// <div class="red">...</div>
// <p class="green red">...</p>

通常很多节点有多个class,我们可以查找同时包含red和green的节点:

var a = $('.red.green'); // 注意没有空格!
// 符合条件的节点:
// <div class="red green">...</div>
// <div class="blue green red">...</div>

(4)、按属性查找

一个DOM节点除了id和class外还可以有很多属性,很多时候按属性查找会非常方便,比如在一个表单中按属性来查找:

var email = $('[name=email]'); // 找出<??? name="email">
var a = $('[items="A B"]'); // 找出<??? items="A B">

(5)、组合查找

组合查找就是把上述简单选择器组合起来使用。如果我们查找$(‘[name=email]’),很可能把表单外的

也找出来,但我们只希望查找,就可以这么写:

var emailInput = $('input[name=email]'); // 不会找出<div name="email">
2、层级选择器

如果两个DOM元素具有层级关系,就可以用$(‘ancestor descendant’)来选择,层级之间用空格隔开。例如:

<!-- HTML结构 -->
<div class="testing">
     <ul class="lang">
         <li class="lang-javascript">JavaScript</li>
         <li class="lang-python">Python</li>
         <li class="lang-lua">Lua</li>
     </ul>
</div>

要选出JavaScript,可以用层级选择器:

$('ul.lang li.lang-javascript');
$('div.testing li.lang-javascript');
3、查找和过滤

最常见的查找是在某个节点的所有子节点中查找,使用find()方法,它本身又接收一个任意的选择器。例如如下的HTML结构:

<!-- HTML结构 -->
<ul class="lang">
     <li class="js dy">JavaScript</li>
     <li class="dy">Python</li>
     <li id="swift">Swift</li>
     <li class="dy">Scheme</li>
      <li name="haskell">Haskell</li>
</ul>

用find()查找:

var ul = $('ul.lang'); // 获得<ul>
var dy = ul.find('.dy'); // 获得JavaScript, Python, Scheme
var swf = ul.find('#swift'); // 获得Swift
var hsk = ul.find('[name=haskell]'); // 获得Haskell

和函数式编程的map、filter类似,jQuery对象也有类似的方法。filter()方法可以过滤掉不符合选择器条件的节点:

var langs = $(‘ul.lang li’); // 拿到JavaScript, Python, Swift, Scheme和Haskell

var a = langs.filter(‘.dy’); // 拿到JavaScript, Python, Scheme

4、操作DOM

(1)、修改Text和HTML:

jQuery对象的text()和html()方法分别获取节点的文本和原始HTML文本,例如,如下的HTML结构:

<!-- HTML结构 -->
<ul id="test-ul">
     <li class="js">JavaScript</li>
     <li name="book">Java & JavaScript</li>
</ul>

分别获取文本和HTML:

$('#test-ul li[name=book]').text();// 'Java & JavaScript'
$('#test-ul li[name=book]').html();//'Java& JavaScript'

(2)、修改CSS

jQuery对象有“批量操作”的特点,这用于修改CSS很方便。 考虑下面的HTML结构:

<!-- HTML结构 -->
<ul id="test-css">
     <li class="lang dy"><span>JavaScript</span></li>
     <li class="lang"><span>Java</span></li>
     <li class="lang dy"><span>Python</span></li>
     <li class="lang"><span>Swift</span></li>
     <li class="lang dy"><span>Scheme</span></li>
</ul>

要高亮显示动态语言,调用jQuery对象的css(‘name’, ‘value’)方法,我们用一行语句实现:

$('#test-cssli.dy>span').css('background-color', '#ffd351').css('color', 'red');

(3)、显示和隐藏DOM

考虑到显示和隐藏DOM元素使用非常普遍,jQuery直接提供show()和hide()方法,我们不用关心它是如何修改display属性的,总之它能正常工作:

var a = $('a[target=_blank]');
a.hide(); // 隐藏
a.show(); // 显示
5、事件

jQuery能够绑定的事件主要包括:

鼠标事件

click: 鼠标单击时触发;

dblclick:鼠标双击时触发;

mouseenter:鼠标进入时触发;

mouseleave:鼠标移出时触发;

mousemove:鼠标在DOM内部移动时触发;

hover:鼠标进入和退出时触发两个函数,相当于mouseenter加上mouseleave。

键盘事件

键盘事件仅作用在当前焦点的DOM上,通常是和。

keydown:键盘按下时触发;

keyup:键盘松开时触发;

keypress:按一次键后触发。

其他事件

focus:当DOM获得焦点时触发;

blur:当DOM失去焦点时触发;

change:当、或的内容改变时触发;

submit:当提交时触发;

ready:当页面被载入并且DOM树完成初始化后触发。

例子:绑定与取消绑定事件

function hello() {
    alert('hello!');
}
a.click(hello); // 绑定事件
// 10秒钟后取消绑定:
setTimeout(function () {
    a.off('click', hello);
}, 10000);

九、JavaScript后端开发

1、Node.js简介

简单的说 Node.js 就是运行在服务端的JavaScript。

Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。

Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。

2、Node的交互模式和直接运行.js文件的区别

直接输入node进入交互模式,相当于启动了Node解释器,但是等待你一行一行地输入源代码,每输入一行就执行一行。

直接运行node hello.js文件相当于启动了Node解释器,然后一次性把hello.js文件的源代码给执行了,你是没有机会以交互的方式输入源代码的。

3、模块

为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Node环境中,一个.js文件就称之为一个模块(module)。

编写模块:

//hello.js
var s = 'Hello';
function greet(name) {
     console.log(s + ', ' + name + '!');
}
module.exports = greet;//作用是把函数greet作为模块的输出暴露出去,这样其他模块就可以使用greet函数了

调用模块:

//main.js
// 引入hello模块:
var greet = require('./hello');
var yx = 'yuxuan';
greet(yx); // Hello, yuxuan!

一个模块想要对外暴露变量(函数也是变量),可以用module.exports = variable;,一个模块要引用其他模块暴露的变量,用var ref = require(‘module_name’);就拿到了引用模块的变量。

4、fs模块

Node.js内置的fs模块就是文件系统模块,负责读写文件。和所有其它JavaScript模块不同的是,fs模块同时提供了异步和同步的方法。

(1)、同步读文件步骤:

  1. 创建一个文件 input.txt ,内容如下:

你好,我是方建康。

Hello!my name is fangjiankang.

  1. 创建 main.js 文件, 代码如下:
var fs = require("fs");

var data = fs.readFileSync('input.txt');

console.log(data.toString());

console.log("程序执行结束!");
  1. 以上代码执行结果如下:

你好,我是方建康。

Hello!my name is fangjiankang.

程序执行结束!

(2). 异步读文件步骤:

  1. 创建一个文件 input.txt ,内容如下:

你好,我是方建康。

Hello!my name is fangjiankang.

 

2. 创建 main.js 文件, 代码如下:
	var fs = require("fs");

	fs.readFile('input.txt', function (err, data) {

	if (err) return console.error(err);

	console.log(data.toString());

	});

	console.log("程序执行结束!");
  1. 以上代码执行结果如下:

程序执行结束!

你好,我是方建康。

Hello!my name is fangjiankang.

(3). 写文件步骤:

  1. 创建一个空文件 output.txt

  2. 创建 main.js 文件, 代码如下:

var fs = require('fs');
    var data = 'Hello, Node.js';
    fs.writeFile('output.txt', data, function (err) {
        if (err) {
            console.log(err);
        } else {
            console.log('ok.');
        }
    });
  1. 执行结果:空文件 output.txt里的内容变为Hello, Node.js
5、Stream模块

stream是Node.js提供的又一个仅在服务区端可用的模块,目的是支持“流”这种数据结构。

Stream 有四种流类型:

Readable - 可读操作。

Writable - 可写操作。

Duplex - 可读可写操作.

Transform - 操作被写入数据,然后读出结果。

所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有:

data - 当有数据可读时触发。

end - 没有更多的数据可读时触发。

error - 在接收和写入过程中发生错误时触发。

finish - 所有数据已被写入到底层系统时触发。

(1)、从流中读取数据:

1.创建 input.txt 文件,内容如下:

hello world !

2.创建 main.js 文件, 代码如下:

var fs = require("fs");
var data = '';

// 创建可读流
var readerStream = fs.createReadStream('input.txt');

// 设置编码为 utf8。
readerStream.setEncoding('UTF8');

// 处理流事件 --> data, end, and error
readerStream.on('data', function(chunk) {
  data += chunk;
});

readerStream.on('end',function(){
  console.log(data);
});

readerStream.on('error', function(err){
  console.log(err.stack);
});

 

console.log("程序执行完毕");

3.以上代码执行结果如下:

程序执行完毕

hello world !

(2)、写入流:

  1. 创建 main.js 文件, 代码如下:
var fs = require("fs");
var data = 'hello world !';

// 创建一个可以写入的流,写入到文件 output.txt 中

var writerStream = fs.createWriteStream('output.txt');

// 使用 utf8 编码写入数据
writerStream.write(data,'UTF8');

// 标记文件末尾
writerStream.end();

// 处理流事件 --> data, end, and error
writerStream.on('finish', function() {
console.log("写入完成。");

});

writerStream.on('error', function(err){
  console.log(err.stack);
});
console.log("程序执行完毕");
  1. 以上程序会将 data 变量的数据写入到 output.txt 文件中。代码执行结果如下:

程序执行完毕

写入完成。

  1. 查看 output.txt 文件的内容:

hello world !

6、http模块

要开发HTTP服务器程序,从头处理TCP连接,解析HTTP是不现实的。这些工作实际上已经由Node.js自带的http模块完成了。应用程序并不直接和HTTP协议打交道,而是操作http模块提供的request和response对象。

实现一个HTTP服务器程序的步骤:

1、引入requried模块:我们使用 require 指令来载入 http 模块,并将实例化的 HTTP 赋值给变量 http,实例如下:

var http = require(“http”);

2、创建服务器,接收请求与响应请求:

	// 创建http server,并传入回调函数:

	var server = http.createServer(function (request, response) 	{

	// 将HTTP响应200写入response

	response.writeHead(200, {'Content-Type': 'text/html'});

	 

	// 将HTTP响应的HTML内容写入response:

	response.end('<h1>Hello world!</h1>');

	});

// 让服务器监听8080端口:

server.listen(8080,‘127.0.0.1’);

// 终端打印如下信息

console.log(‘Server is running at http://127.0.0.1:8080/’);

3、在命令提示符下运行该程序,可以看到以下输出:

Server is running at http://127.0.0.1:8080/

4、不要关闭命令提示符,直接打开浏览器输http://127.0.0.1:8080,即可看到服务器响应的内容:

Hello world!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值