node.js(一)

序言

JS
Javascript 简称JS,是一种动态的弱类型脚本解释型语言,和HTML、CSS并称三大WEB核心技术.
ES
ES,ECMAScript是由ECMA国际通过ECMA-262标准化的脚本程序设计语言。
该语言被广泛应用于互联网。

JavaScript是商品名,根据ES标准,有很多实现引擎,其中包括JavaScript。

为什么之前浏览器兼容是个大问题?
运行HTML、CSS、JS技术都在发展,标准版本很多。浏览器内嵌的引擎实现不太一致,甚至有些不按照标准实现,
或减少实现,或改变实现,或增加功能的实现,比如IE,这就导致了开发人员负担,很难做到一套代码可以兼容的
跑在多种浏览器中,甚至不能跑在同一种浏览器的不同版本中。

1997年,指定首个版本ECMA-262
1999年12月,ES 3,支持更强大的正则表达式等
ES4太激进,最终放弃
2009年,ES5发布,得到广泛支持,支持严格模式,支持Json。
2015年,ES6发布,引入非常多的新的语言特性,还兼容旧版本特性。ES6之前按照版本号命名。
从ES6开始使用年份作为版本号,ES6即ESCMAScript2015。

V8
就在浏览器市场一家独大的时候,Firefox、chrome异军突起。
20008年9月2日,Google的chrome浏览器发布,一并发布的Js引擎,就是V8引擎。V8使用BSD协议。
V8引擎使用C++开发,将JavaScript编译成了机器码,而不是字节码,还是用很多优化方法提高性能,因此V8引擎速度非常快。
V8引擎还可以独立运行,可以嵌入到其他任何C++程序中。
V8引擎的诞生,使得服务器端运行JS成为了方便的事情。

Nodejs

Nodejs是服务器端运行服务器端运行JavaScript的开源、跨平台运行环境。
Nodejs原始作者瑞安.达尔,于2009年发布,使用V8引擎,并采用事件驱动,非阻塞和异步IO模型。
2010年,npm软件包管理器诞生了,通过它可以方便的发布、分析Nodejs的库和源代码。
Nodejs4.0引入了ES6语言特性。
我们学习JS,就是让它跑在最新版的Nodejs上,为了调试方便,也为了使用最新的ES2017特性。

安装
文档 http://nodejs.cn/download/
开发
搜索MDN,Mozilla Developer Network,提供非常完善的HTML、CSS、JS等的技术资料。
文档 https://developer.mozilla.org/zh-CN/
指南 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide

ES6 语法参考 https://es6.ruanyifeng.com/#docs

语法入门

常量和变量

标识符
标识符必须是字母、下划线、美元符号和数字,但必须是字母、下划线、美元符号开头,依然是不能数字开头就行。
标识符区分大小写

1. var 和 let

在之前声明变量常用var,类似如下

var name;  // 声明一个变量name

ES6 中新增了let,与var使用类似

let name;  // 声明一个变量name

let 与var最大不同,let声明的变量会限制在所在代码块内,

{
var name="张三"let age=19}
console.log(name);  //打印name正常
console.log(age);  // 打印age报错

报错信息如下

[Running] node "/home/zhaow/vscode_workspace/C_code/test.js"
张三
/home/zhaow/vscode_workspace/C_code/test.js:6
    console.log(age);  

使用let的变量必须先声明后使用,否则会报错。

2. 数据类型

• number 数值型,包括整型和浮点型
• boolean 布尔类型, ture和false( undefined, 0 Nan, null, 空字符串(’’) 均为false , 其他均为真值)
• string 字符串
• null 空值
• undefined 变量未赋值;对象未定义的属性
• symbol ES6 新引入类型
• object 是以上基本类型的复合类型

3. 类型转换

示例代码

//字符串
console.log(a = 3 + 'welcome', typeof(a))
console.log(a = null + 'welcome', typeof(a))
console.log(a = undefined + 'welcome', typeof(a))
console.log(a = true + 'welcome', typeof(a))
/** 输出结果
3welcome string
nullwelcome string
undefinedwelcome string
truewelcome string
*/

//数字
console.log(a = null + 8, typeof(a))
console.log(a = undefined + 8, typeof(a))
console.log(a = true + 8, typeof(a))
console.log(a = false + 8, typeof(a))
/** 输出结果
8 number
NaN number
9 number
8 number
*/

//boolean
console.log(a = null + true, typeof(a))
console.log(a = null + false, typeof(a))
console.log(a = undefined + true, typeof(a))
console.log(a = undefined + false, typeof(a))
console.log(a = null & true, typeof(a))
/** 输出结果
1 number
0 number
NaN number
NaN number
0 number
***********
*/

//null
console.log(a = null + undefined, typeof(a))
/**
NaN number
*/

可以总结

• 遇到字符串类型时,加号作用就是拼接字符串,所有非字符串隐式转换为字符串。
• 如果没有字符串,加号把其他所有类型都当做数字处理,非数字类型隐式转换为数字。
• undefined特殊,因为它没有定义值,所以是特殊数字Nan
• 如果运算符是逻辑运算符,短路符,返回就是短路时的类型,没有隐式转换。

3. 变量的引用 反引号`和$

let name = 'tom';
var age = 18let c = `I am ${name}, ${age}`; //这里是反引号,使用$符号引用变量
console.log(c)

4. 字符串常用操作

示例

let url = 'www.baidu.com';
console.log(url.charAt(2));  // 索引2的字符
console.log(url[2]);  // 索引2的字符
console.log(url.slice(3)); // 切片操作,如果只有一个参数,则从第3个字符开始,取到最后
console.log(url.slice(3,5));
console.log(url.split('.')); // 切割字符串
console.log(url.indexOf('w')); // 查找字符的索引位置
console.log(url.substr(3,4)); //从何处开始取,取多长
console.log(url.substring(3,10)); //取子串,从何处开始,到何处结束

5. 数值常用的方法

示例

Number.parseFloat()  //转换为浮点数
Number.parseInt()  //转换为整数
Number.isFinite()  //是否为有限数字
Number.isInteger()  //是否为整数
Number.isNaN()  //是否为非数字
//或者省略Number
parseFloat()
parseInt()
isFinite()
isInteger()
isNaN()

数值类型,还有一些常量属性

var  biggenum = Number.MAX_VALUE;  // 最大值
var samllletnum = Number.MIN_VALUE; // 最小值
var infinitenum = Number.POSITIVE_INFINITY // 正无穷
var neginfinetnum = Number.NEGATIVE_INFINITY  // 负无穷
var notAnum = Number.NaN  // 非数字

6. 对象Object

var a = new String('abc');  // 使用new关键字定义,a就是一个object类型
console.log(a instanceof String); // 对象类型判定
console.log(typeof(a)); // 输出变量的类型
console.log(typeof(typeof(100)))
/** 输出结果
true
object
string
*/

7.数组的操作

  • 示例1 数组中,删除其中某个值时,其位置还在,是undefined
var trees = new Array('a', 'b', 'c', 'd', 'e');
delete trees[3];  //数组中索引3的元组值被删除,但位置还在,是undefined
console.log(trees[3])
/** 输出结果
undefined
*/

  • 示例2 数组的遍历
var trees = new Array('a', 'b', 'c', 'd', 'e');
for(var i=0; i<trees.length; i++){
    console.log(trees[i])
}

  • 示例3 in的使用说明
var trees = new Array('a', 'b', 'c', 'd', 'e');
delete trees[3];
console.log(0 in trees);  // true, 0代表数组的索引
console.log(1 in trees);  // true,  1代表数组的索引
console.log('a' in trees);  //false 
console.log('length' in trees); //true length 是数组的属性
console.log(3 in trees);  //false 因为3位置虽然在,但没有定义的元素

8.生成器的使用

使用function* func_name(){} 定义,ES6开始支持

function* inc(){
    let i = 0;
    while(1){  // 1表示true ,可以直接while(true){};
        yield (++i);
    };
};

9. 解构 …

var parts = ['shoulder', 'knees'];
var lyris = ['head', ...parts, 'and', 'toes'];  // 使用... 解构

console.log(lyris);
/**输出结果
[ 'head', 'shoulder', 'knees', 'and', 'toes' ]
*/

10.语句块

ES6之前语句块没有作用域,从ES6开始支持。

{
	let a=6;  // 使用大括号定义语句块,ES6有作用域
}

11.控制语句

//流程控制if语句
if(){
}else if(){
}
else{
};


//switch...case分支语句
a = 3;
switch(a) {
    case 1:
        console.log('1')
        break
    case 2:
        console.log('2')
        break;
    default:
        console.log('3')
};
//for 循环
let sum = 0;
for(let i=1;i<10;i++){
    sum += i;
};

let arr = [10, 20 ,30, 40]
for(x=0,y=100;x<arr.length;x+=1){
    console.log(x,arr[x],y)
};

//while循环和do..,while循环
let i = 15;
while(i--){
    console.log(i);
}

let x = 15;
do{
    console.log(x);
}while(x--)


//for in 循环
let arr = ['a', 'b', 'c'];
for (x in arr){  //遍历的是索引
    console.log(x);
};

//for of 循环ES6 才有的,of后面必须是迭代器,不能迭代对象
let arr = ['a', 'b', 'c'];
for(x of arr){
    console.log(x);    //遍历数组元素
};

12.函数

//函数########################################################
function 函数名(参数列表){
    函数体;
    return 返回值;
}//函数表达式
//使用表达式来定义函数,表达式的函数名可以省略,如果这个函数名不省略,只能放在函数内部。
let add = function _add(x, y){
    return x+y;
};
console.log(add(4,5))

const sum = function _sum(n){
    let result = 0;
    if (n == 1){
        return 1
    }else{
        return result += n + _sum(--n);
    };
};

高阶函数示例 – map函数

function map(fn, arr){
    let new_arr = [];
    for(i in arr){
        new_arr[i] = fn(arr[i])
    };
    return new_arr;
};
let new_arr = map(function(x){return x*2}, [1,2,3,4]);
console.log(new_arr)

箭头函数

let map = function (fn, arr){
    let new_arr = [];
    for(i in arr){
        new_arr[i] = fn(arr[i])
    };
    return new_arr;
};

let map = (fn, arr) => {
    let new_arr = [];
    for(i in arr){
        new_arr[i] = fn(arr[i])
    };
    return new_arr;
};

//如果箭头后为大括号,就必须有return语句
let new_arr = map((x) => {return x*2}, [1,2,3,4]);
let new_arr = map(x =>  x*2, [1,2,3,4]);

/**
• 箭头函数参数,如果一个函数没有参数,使用()
• 如果只有一个参数,参数列表可以省略小括号
• 多个参数不能省略小括号
• 箭头函数返回值,多行不能省略大括号,且必须有return语句。
• 一行,可以写成 x => x*2
*/

//函数参数
//一个参数占一个位置,支持默认参数
//JS根本没有Python中的关键字参数传参,S中只是做参数位置对应
//JS并不限制默认参数的位置
function add(x,y){
	return x+y
};
add(a=2,y=3)  //相当于add(2,3)  因为JS没有关键字传参

//可变参数function add(...args){};###################
//函数所有参数都保存一个arguments键值表中。
//ES6之前使用arguments,但ES6不推荐使用,推荐可变参数写法。

//参数解构
const add = (...args) => {
    console.log(args);
    console.log(arguments);
};
arr = [1,2,3,4]
// add(arr)
// add(1,2,3,4)
add(...arr)

13.对象模型

早期

//字面式声明方式///////////////////////////////////////
//第一种构造方式
var obj = {
    a:'abc'
};
//第二种
//定义一个函数(构造器)对象,使用this定义属性
// this与java中this不是一码事,不要混为一谈
//使用关键字new和构造器创建一个新对象
function A(x){
    this.x = x;
    this.show = () => console.log(this, this.x)
};
a = new A(100); //new关键字声明,对象构建
console.log(typeof(a));

//继承使用call方法
function B(x,y,z){
    A.call(this, x);
    this.y=y;
    this.z=z;
}
b = new B(10,100,1000)
console.log(B)
console.log(b)
b.show()
//总结
//new 构建一个新的通用对象,new操作符会将新对象的this值传递给构造器。
//new后得到一个对象,使用this调用构造器

ES6中

class Point{    // 使用class关键字
    constructor (x, y) {   //定义构造器 必须存在, 一个类只能有一个constructor构造器方法
        this.x = x;
        this.y = y;
        console.log('Point~~~~~~~~~~~~~')
    } ;

    show(){
        console.log(this, this.x, this.y)
    }
};
a = new Point(100,1000)
console.log(Point)
console.log(a.x)
console.log(a.y)
a.show()
//类定义必须使用class关键字,创建的本质还是函数。
//类没有私有属性
//继承使用extends关键字
//一个构造器可以使用super关键字来调用一个父类的构造函数。
class Point3D extends Point{
    constructor (x,y,z){
        super(x,y);
        this.z = z;
    };
    show(){
        console.log(this, this.x, this.y, this.z)
    };
};

// JS类中没有重载一说,只有重写或者覆盖
// 如果需要调用父类的方法,只写使用super.method()即可
// 类方法中,优先使用构造器中的属性定义的方法
// 继承时,要统一定义方法形式,或者都采用属性,或者使用方法定义。

// 静态属性目前还没有得到很好的支持
// 静态方法 方法名前加static关键字,与python不同,这里的静态方法就是类方法
// 静态方法只能用类调用,实例无法直接调用,必须借助构造器关键字constructor调用

14.异常

try {
    throw 1;
}
catch(error){
    console.log(error);
}finally{
}; //没有多catch
//使用关键字throw 抛出异常

15.this

var school = {
    name:'weilcome',
    getNameFunc: function () {
        console.log('1',this.name);
        console.log('2',this==globalThis);
        console.log('~~~~~~~~~~~~~~~~~~~~~~');
        return function() {
            console.log('3',this == globalThis);
            return this.name;
        };
    }
};
//函数执行时,会开启新的执行上下文环境ExecutionContext。
//创建this属性,但是this是什么就要看函数是怎么调用的了。
/**
• 1。myFunction(1,2,3) 普通函数调用方式,this指向globalthis(nodejs的global或者浏览器的window)
• 2.myObject.myFunction(1,2,3),对象方法调用方式,this指向包含该方法的对象。
• 3 call和apply方法调用,要看第一个参数是谁。
 * 4 箭头函数中this又有不同,它指向为外层函数,不需要担心this指向问题。
*/

继承

//普通继承
class A extends Object {};
//匿名继承
const B = class extends Object{
    constructor () {
        super();
        console.log('B constructor');
    };
};
发布了21 篇原创文章 · 获赞 0 · 访问量 313

猜你喜欢

转载自blog.csdn.net/qq_38756978/article/details/105589762