zoukankan      html  css  js  c++  java
  • 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 = 18;
    let 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');
        };
    };
    
  • 相关阅读:
    前端性能优化方案-路由懒加载实现
    写 React / Vue 项目时为什么要在列表组件中写 key,其作用是什么
    自定义组件实现双向绑定v-model
    前端开发中如何快速定位问题
    修改浏览器属性配置的作用---开发机上解决跨域的方式
    vue展示md文件,前端读取展示markdown文件
    js数组去重
    VUE错误码Attribute ':sizeOpts' must be hyphenated
    前端开发-日常开发沉淀之git提交文件忽略
    创建一个新的分支并关联远程分支
  • 原文地址:https://www.cnblogs.com/luckyleaf/p/12723486.html
Copyright © 2011-2022 走看看