JavaScript基础语法

js是动态的、弱类型的、解释型、多用于浏览器的脚本语言。
用于服务端的node.js.
浏览器端的js可以调用浏览器的各种对象,可以进行Dom/BOM操作。
服务端的js可以进行io、调用数据库等操作。
ECMAScript是一种规范,JS实现了该规范,前后端都适用。
TypeScript是一种在JS上进行增强的语言,多数功能也实现了ES。

一、浏览器中js的功能

当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)
浏览器对象模型(Browser Object Model (BOM))允许 JavaScript 与浏览器对话
通过这两个模型,js能动态操作页面的所有内容和浏览器的各种功能。

HTML DOM 模型被结构化为对象树。

如通过Dom中某button对象的属性,触发函数,与Bom对象window进行交互。

<button onclick="alertTitle()">弹出</button>

    <script>
        document.writeln("写入")
        document.write("数据")
        function alertTitle(){
            window.alert("Hello Alert")
        }
    </script>

<!--window.alert中window可以省略,默认是window对象-->
 <script src="xx.js"></script>
js可以通过script标签直接嵌入html中使用,也可以从外部引入js文件使用

二、使用

001、Dom

通过document对象可以获取各个dom对象,并且动态修改。
document可以通过id、class、nodename等各种方式获取节点对象。
 <h1 id="h_id">hello 我是标签</h1>

    <script>
        document.write("nice","ok") 
        document.getElementById("h_id").style="color:red"
    </script>

002、Bom

常用的浏览器对象有Window,直接使用即可。
使用浏览器提供的交互功能在本地存储一个数据,再打印到浏览器控制台。
localStorage经常用来保存后台传来的token。
IndexDB
        localStorage.setItem("name","Tom Blue")
        console.log(localStorage.name)

003、变量

js是动态语言,使用var声明变量,当然不用var也可
var v1="hello"
console.log(v1)

v2="world"
console.log(v2)

hello
world

变量提升

变量提升:函数声明和变量声明总是会被解释器悄悄地被"提升"到方法体的最顶部。
JavaScript 只有声明的变量会提升,初始化的不会

console.log(v1) 
var v1="ok"
此时显示undefined,v1的初始值不会被提示到顶部。

console.log(v2)如果直接输出v2会报错,因为没有v2

let、const

let是ES中推荐的定义方式,默认情况下javascript中并没有块级(block)作用域,let则是块级定义域
let 关键词声明的变量不具备变量提升(hoisting)特性
let 和 const 声明只在最靠近的一个块中(花括号内)有效
当使用常量 const 声明时,请使用大写变量,如:CAPITAL_CASING
const 在声明时必须被赋值

let v=1;
const V_NAME="const"

004、运算符

多数语言运算符都类似,挑几个js中比较特殊的运算符。
==只比较值,===比较值和类型。
let v1="1"
let v2=1
console.log(v1==v2) true
console.log(v1===v2) false

比较运算符

运算符 描述
== 等于
=== 等值等型
!= 不相等
!== 不等值或不等型
> 大于
< 小于
>= 大于或等于
<= 小于或等于
? 三元运算符

类型运算符

运算符 描述
typeof 返回变量的类型。
instanceof 返回 true,如果对象是对象类型的实例。

005、函数

函数是编程语言的基本功能,在js中发挥很大的作用,Js的面向对象功能也能通过函数模拟。
//使用关键字即可声明函数。
function print_msg(info){
    console.log("info : "+info)
}

//js语法比较松散,不检查参数,多了少了也无所谓
print_msg("打印消息")
print_msg("打印消息","ok")
print_msg()


info : 打印消息
info : 打印消息
info : undefined

//Es中扩展了功能,可以接受多参数进入
function print_msg(...info){
    console.log("info : "+info)
}

事件

事件就是发生的事情,也可以说是传递消息的机制。
下面是一些常见的HTML事件的列表:
onchange 	HTML 元素改变
onclick 	用户点击 HTML 元素
onmouseover 	用户在一个HTML元素上移动鼠标
onmouseout 	用户从一个HTML元素上移开鼠标
onkeydown 	用户按下键盘按键
onload 	浏览器已完成页面的加载

<!--1、事件被触发后就会执行相应功能-->
<button onclick="this.innerHTML=Date()">现在的时间是?</button>
<!--2、事件常与函数结合-->
<button onclick="alertTitle()">弹出</button>
    <script>
        function alertTitle(){
            window.alert("Hello Alert")
        }
    </script>


<!--3、通过addEventListener() 方法用于向指定元素添加事件句柄-->
<button id="myBtn">弹出</button>
<script>
document.getElementById("myBtn").addEventListener("click", function(){
	alert("hello")
});
</script>

闭包

js、go、python等语言中都有闭包,所以闭包到底是不是bug。
闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰。
直观的说就是形成一个不销毁的栈环境。

var add=function(){
    var id=0;
    return function(){
        id+=1;
        console.log(id)
    }

}();//此处执行了方法,返回了一个函数

add();1  //此时的add是内部的函数,引用了父函数的id变量
add();2//所以id变量不能被销毁,且只能通过add处理
add();3//id是在匿名函数中定义的,所以此时相当于私有变量


箭头函数、this

面向对象语言中 this 表示当前对象的一个引用。

但在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变。

    在方法中,this 表示该方法所属的对象。
    如果单独使用,this 表示全局对象。
    在函数中,this 表示全局对象。
    在函数中,在严格模式下,this 是未定义的(undefined)。
    在事件中,this 表示接收事件的元素。
    类似 call() 和 apply() 方法可以将 this 引用到任何对象。
    
    
 //Es6中提供了箭头函数,可以简化操作  
var hi=()=>{
    return 10;
}
var hi=()=>10

//在函数中,this通常指向全局对象window,箭头函数中的this指向自身

006、数据类型

字符串值String,数值Number,布尔值Boolean,数组Array,对象Object。
面向对象的角度来看,一切都可以归于对象。

js中的数值型只有一种,可以是整形,也可以是浮点型.
let n1=12
n2=11.2
n3=123e5
 console.log(n1)12
 console.log(n2)11.2
 console.log(n3)12300000

数组

var cars=new Array();
cars[0]="Saab";
cars[1]="Volvo";
cars[2]="BMW";

var cars=new Array("Saab","Volvo","BMW");
var cars=["Saab","Volvo","BMW"];
这三种方式产生的数组是一样的,使用new关键字创建数组。
push() 往数组最后面添加一个元素,成功返回当前数组的长度
pop() 删除数组的最后一个元素,成功返回删除元素的值
shift() 删除数组的第一个元素,成功返回删除元素的值
unshift() 往数组最前面添加一个元素,成功返回当前数组的长度
splice() 有三个参数,第一个是想要删除的元素的下标(必选),第二个是想要删除的个数(必选),第三个是删除
后想要在原位置替换的值(可选)
sort() 使数组按照字符编码默认从小到大排序,成功返回排序后的数组
reverse() 将数组倒序,成功返回倒序后的数组

n=cars.push("BYD");
console.log(n)
console.log(cars)
cars.sort()
console.log(cars)

4
[ 'Saab', 'Volvo', 'BMW', 'BYD' ]
[ 'BMW', 'BYD', 'Saab', 'Volvo' ]

对象

对象使用{}表示,js使用面向对象进行描述。
js中属性名可用双引号包裹
var car = {
    type:"Fiat",
    "model":500,
    color:"white",
    //方法
    run:function(){
        console.log("run....")
    }
}; 
car.info=function(){
    console.log(this.color+this.type+this.model)
}
console.log(car)
car.run()
car.info()


{ type: 'Fiat', model: 500, color: 'white', run: [Function: run] }
run....
whiteFiat500

js中对象的定义有多种方式,以上直接赋值的方式只能使用一次。
可以使用函数声明对象,模拟面向对象,有构造器、类方法等。
使用ES6提供的class、constructor关键字创建对象,和java、python等十分相似。

function Car(type,color){
    //使用函数模拟类,this关键字在这里指向当前对象,不使用this则属性不和对象挂钩
    this.type=type;
    this.color=color;
    this.run=function(){
        console.log(color+type+" run....")
    }
}

//使用new可以创建对象
var c=new Car("BYD","yellow");

//对象方法,只属于该对象
c.info=function(){
    console.log(this.color+this.type)
}
//实例方法,挂载到原型链上,所有实例对象都可使用
Car.prototype.hi=function(){
    console.log("hi")
}
//类方法、只允许类调用
Car.hello=()=>{
    console.log("Hello")
}



ES提供的class、constructor关键字使js对象可以像java等语言一样声明对象,不过这只是语法糖。
class Person {
    constructor(names,age,word){
        //此处的word只是函数参数,不属于整个对象,其他方法中无效
        this.names=names;
        this.age=age;
        console.log("name:"+names+" age:"+age+" word:"+word)
    }
    disPlay(){
        //此处可以获取到下文挂到原型链上的word属性
        console.log("name:"+this.names+" age:"+this.age+" word:"+this.word)
    }
}

//这里将word挂到原型链上,因此对象也有了word属性
Person.prototype.word="ES";
//Person.word="SSS";这相当于是类属性了,只有类能访问
var p=new Person("jack",10,"ES6面向对象");
p.disPlay();

name:jack age:10 word:ES6面向对象
name:jack age:10 word:ES

原型与原型链

每个函数都有一个 prototype 属性
每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。
每一个JavaScript对象(除了 null )都具有的一个属性,叫proto,这个属性会指向该对象的原型。
每个原型都有一个 constructor 属性指向关联的构造函数 实例原型指向构造函数
Es的class只是语法糖,最终也解释成函数,如下:

console.log(Person.prototype==p.__proto__) //true
console.log(p.__proto__.constructor==Person) //true

007、严格模式

"use strict" 指令在 JavaScript 1.8.5 (ECMAScript5) 中新增。
它不是一条语句,但是是一个字面量表达式,在 JavaScript 旧版本中会被忽略。
"use strict" 的目的是指定代码在严格条件下执行。
严格模式下你不能使用未声明的变量。

"use strict";
x = 3.14;       // 报错 (x 未定义)

008、流程

判断、循环

var a=100;

if(a>10){
    console.log(`a: ${a}`) //Es6提供的字符串模板插值
}else if(a>20){ //顺序执行,此处已经跳过
    console.log(`a: ${a}`)
}else{
    console.log(`a: ${a}`)
}


//while循环
while(a>=100){
    a-=10;
    console.log(`a: ${a}`)
}
//for循环
for(;a<100;a++){
    console.log(a)
}

switch语句

var d=new Date().getDay(); 
var x;
switch (d) //根据d的值选择执行case
{ 
  case 0:x="今天是星期日"; 
  break;  //遇到则结束代码块,否则继续向下全部执行
  case 1:x="今天是星期一"; 
  break 
  case 2:x="今天是星期二"; 
  break
  case 3:x="今天是星期三"; 
  break
  case 4:x="今天是星期四"; 
  break;
  case 5:x="今天是星期五"; 
  break;
  default:x="今天是星期六"; 
   
}
console.log(`${x}`)

continue\break:下一迭代\结束代码

009、回调函数

//回调函数在父函数执行时被调用,所以叫回调,在js中常用

function call(callback,msg){
    
    console.log(msg)
    callback();//传入的参数是个函数
}

//直接传入一个匿名函数作为回调函数
call(function(){
    console.log("这是回调函数")
},"Hello Callback Func")

010、常用对象

Date对象

Date.prototype.format = function(fmt){
    var o = {
      "M+" : this.getMonth()+1,                 //月份
      "d+" : this.getDate(),                    //日
      "h+" : this.getHours(),                   //小时
      "m+" : this.getMinutes(),                 //分
      "s+" : this.getSeconds(),                 //秒
      "q+" : Math.floor((this.getMonth()+3)/3), //季度
      "S"  : this.getMilliseconds()             //毫秒
    };
  
    if(/(y+)/.test(fmt)){
      fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
    }
          
    for(var k in o){
      if(new RegExp("("+ k +")").test(fmt)){
        fmt = fmt.replace(
          RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));  
      }       
    }
  
    return fmt;
  }


console.log( new Date().format("yyyy-MM-dd hh:mm:ss"))
console.log( new Date().format("yyyy年-MM月-dd日"))
console.log( new Date().format("yyyy/MM/dd"))

数组对象

push() 往数组最后面添加一个元素,成功返回当前数组的长度
pop() 删除数组的最后一个元素,成功返回删除元素的值
shift() 删除数组的第一个元素,成功返回删除元素的值
unshift() 往数组最前面添加一个元素,成功返回当前数组的长度
splice() 有三个参数,第一个是想要删除的元素的下标(必选),第二个是想要删除的个数(必选),第三个是删除
后想要在原位置替换的值(可选)
sort() 使数组按照字符编码默认从小到大排序,成功返回排序后的数组
reverse() 将数组倒序,成功返回倒序后的数组
concat()
join()
toString()
map()通过指定函数处理数组的每个元素,并返回处理后的数组。
forEach()数组每个元素都执行一次回调函数。
filter()检测数值元素,并返回符合条件所有元素的数组。
fill()通过给定数据填充数组
from() 类方法,通过字符串返回数组

var arr=new Array("hello","world","Good","Nice");
//map
var s=arr.map(msg=>msg+"001")
console.log(s) [ 'hello001', 'world001', 'Good001', 'Nice001' ]
//forEach
arr.forEach((item,index,arr)=>{
    console.log(item)
})

//filter
var s2=arr.filter(msg=>{
    return msg.length>4
})

console.log(s2)  [ 'hello', 'world' ]

//Array.from
console.log(Array.from("ok"))

//fill
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.fill("food", 2, 4);
console.log(fruits)[ 'Banana', 'Orange', 'food', 'food' ]

Math对象

round()四舍五入,ceil()/floor()向上、下进行舍入
random()返回 0 到 1 之间的随机数。
max(...)  返回最大参数
min(...)
pow(x,y)返回x的y次幂
abs()绝对值
sqrt()平方根



//根据上下限生成随机数:
var rand = (min,max) => Math.round(Math.random()*(max-min))+min;

//根据长度随机字符串
function randChar(length){
    characters="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    //length为所需长度,characters为所包含的所有字符,默认为字母+数字。
    characters=characters.split("");//分割字符。
    result="";//返回的结果。
    while(result.length<length) result+=characters[Math.round(Math.random()*characters.length) - 1];
    return result;
  }

//随机从数组中取出一个
Array.prototype.pick=function(){
    return this[(this.length?Math.round(Math.random()*(this.length-1)):undefined)]; 
}

String对象

属性:

    length
    prototype
    constructor

方法:
    charAt()
    charCodeAt()
    concat()
    fromCharCode()
    indexOf()
    lastIndexOf()
    match()
    replace()
    search()
    slice()
    split()
    substr()
    substring()
    toLowerCase()
    toUpperCase()
    valueOf()

var str="Hello world"
console.log(str.length) 11
console.log(str.split(" "))  [ 'Hello', 'world' ]
console.log(str.slice(0,3)) Hel

模块化

Js的模块体系主要有AMD、CommonJs、ES6,前者用于浏览器,后者用于服务器。
ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。


在CommonJs中,使用exports.xx=yy导出,使用require('xx')导入
//ex.js
var hi=function(){
    console.log("hi hi hi ")
}

exports.hi=hi //导出hi

//导入,想当于把文件暴露的模块全部导入
x=require("./ex")
x.hi()  //这里也要和导出文件对应


Es6的模块话使用export,import
export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系,不可导出变量
import导入必须和导出变量名一致,当使用export default时无需

//Es模块如果使用在服务端,可能会有不兼容的问题,可以把文件名改为x.mjs或者在配置文件中处理
export {hi}; //导出
import {hi} from "ex" //导入

JSON

JSON 英文全称 JavaScript Object Notation
JSON 是用于存储和传输数据的格式,通常用于服务端向网页传递数据,与语言无关,序列化友好。 
JSON还用于配置信息,不过多用于前端。

JSON语法:
    数据为 键/值 对,键(字符串)必须使用双引号(单引号不行)。
    键值用分号隔开,
    数据由逗号分隔。
    大括号保存对象
    方括号保存数组
JSON组成:
	对象、数组、字符串、数值,布尔值
    
//JS提供的处理json的函数
JSON.parse()	用于将一个 JSON 字符串转换为 JavaScript 对象。
JSON.stringify()	用于将 JavaScript 值转换为 JSON 字符串。

//这是一个js对象,虽然和JSOn格式一样
var json={
    "name":["Tom","JIm","Sally"],
    "age":18,
    "desc":"All are students"
}

console.log(json)
console.log(JSON.stringify(json))
console.log(JSON.parse(JSON.stringify(json)))

{ name: [ 'Tom', 'JIm', 'Sally' ], age: 18, desc: 'All are students' }
{"name":["Tom","JIm","Sally"],"age":18,"desc":"All are students"}
{ name: [ 'Tom', 'JIm', 'Sally' ], age: 18, desc: 'All are students' }

异步方法

AJax

三、Es语法

001、for ..of、for ... in、iterator

//forEach、map等方法可以方便的操作数组,如下
arr=[10,23,12,34]

arr.forEach(e=>{
    console.log(e)
})

//es6也提供了增强for和迭代器
//for ...of获取到元素
for(var e of arr){
    console.log(e)
}

//for...in 获取到属性
for(var i in arr){
    console.log("属性: "+i,"值: "+arr[i])
}


//迭代器,其中value表示当前的数据的值,done是一个布尔值,表示遍历是否结束。
var iter=arr[Symbol.iterator]()
console.log(iter.next().value)

var str ="hellonice";
var it=str[Symbol.iterator]();
console.log(it.next())

//支持迭代器的原生类型:
    Array
    Map
    Set
    String
    TypedArray
    函数的 arguments 对象
    NodeList 对象


002、Promise

Promise 是异步编程的一种解决方案,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。

var ok=new Promise(function(resolve,reject){
    var i=10;
    if(i>1){
        resolve("hello")
    }else{
        reject("nice")
    }
})

//异步
ok.then(res=>{
    console.log(res)
})

003、Generator

//使用*表示
function *outMsg(){

    console.log("nice")
    yield "one";
    yield "Two";
    return "three";
}

var msg=outMsg();//返回一个迭代器,value为yield的值

console.log(msg.next())


posted @ 2020-12-28 09:45  cgl_dong  阅读(181)  评论(0编辑  收藏  举报